spring声明式事务

一、传统事务

二、通过spring配置完成事务:

1、配置spring,加入spring的jar包,加入spring的配置文件

2、配置数据源,这里使用c3p0,加入c3p0 jar包和mysql数据库驱动包,配置

<context:property-placeholder location="classpath:db.properties" />

 

<!-- 配置数据源 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

 

3、配置spring jdbcTemplate

<!-- 配置jdbcTemplate -->
    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

4、配置事务管理器和spring注解事务

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

 

完整的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <context:property-placeholder location="classpath:db.properties" />
    <context:component-scan base-package="com.hy"></context:component-scan>
    <!-- 配置数据源 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

    <!-- 配置jdbcTemplate -->
    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

三、编写一个测试实例:

这里使用简单三表演示,用户、图书、库存三表

package com.hy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hy.dao.BookShopDao;
import com.hy.service.BookShopService;

public class TestSpringTransaction {
    
    private ApplicationContext app;
    
    private BookShopDao bookShopDao;
    
    private BookShopService bookShopService;
    
    {
        app = new ClassPathXmlApplicationContext("applicationContext.xml");
        bookShopDao = app.getBean(BookShopDao.class);
        bookShopService = app.getBean(BookShopService.class);
    }
    
    
    @Test
    public void testFindPriceByIsbn() {
        System.out.println(bookShopDao.findBookPriceByIsbn("1001"));
    }
    
    @Test
    public void testUpdateStock() {
        bookShopDao.updateBookStock("1001");
    }
    
    @Test
    public void testUpdateAccount() {
        bookShopDao.updateUserAccount("AA", 100);
    }
    
    
    @Test
    public void testPurchase() {
        bookShopService.purchaseBook("AA", "1001");
    }
    

}

 

此处使用了注解执行事务:

dao注解:

package com.hy.dao;

import java.net.SocketException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.hy.exception.AccountException;
import com.hy.exception.StockException;

@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int findBookPriceByIsbn(String isbn) {
        String sql = "select price from book where isbn = ?";
        return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
    }

    @Override
    public void updateBookStock(String isbn) {
        String sql2 = "select stock from book_stock where isbn = ?";
        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
        if (stock == 0) {
            throw new StockException("库存不足");
        }
        
        String sql = "update book_stock set stock = stock - 1 where isbn = ?";
        jdbcTemplate.update(sql, isbn);
    }

    @Override
    public void updateUserAccount(String username, int price) {
        String sql2 = "select balance from account where username = ?";
        int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);
        if (balance < price) {
            throw new AccountException("余额不足");
        }
        
        String sql = "update account set balance = balance - ? where username = ?";
        jdbcTemplate.update(sql, price, username);

    }

}

service注解:

package com.hy.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hy.dao.BookShopDao;

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {

    @Autowired
    private BookShopDao bookShopDao;
    
    @Transactional
    @Override
    public void purchaseBook(String username, String isbn) {
        int price = bookShopDao.findBookPriceByIsbn(isbn);
        bookShopDao.updateBookStock(isbn);
        bookShopDao.updateUserAccount(username, price);
    }

}

包扫描配置:

<context:component-scan base-package="com.hy"></context:component-scan>

 

 

附录:源代码链接:

http://pan.baidu.com/s/1cJzTLk

posted on 2016-12-07 23:34  _故乡的原风景  阅读(261)  评论(0编辑  收藏  举报