首页 > 代码库 > Spring初学之spring的事务管理注解

Spring初学之spring的事务管理注解

spring的事务管理,本文的例子是:比如你需要网购一本书,卖书的那一方有库存量以及书的价格,你有账户余额。回想我们在编程中要实现买书这样的功能,由于你的账户表和书的库存量表肯定不是同一张数据库表,所以必定会有一个先后,要么先将账户余额扣除书的价格,紧接着将书的库存量减一,要么反过来。那么问题来了,假如我们先将你的账户余额减掉,然后发现书的库存不足,这时怎么办呢,这就需要事务了,当我们发现书的库存不足时就要回滚事务,将你的余额返回去。只要配置了事务,发生了异常,就回滚。这就是事务的回滚。注:新人理解,如有错误,望指正,谢谢。

 配置文件applicationContext.xml:

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:p="http://www.springframework.org/schema/p"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
 9         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
10 
11     <!-- 导入资源文件 -->
12     <context:property-placeholder location="classpath:jdbc.properties"/>
13     
14     <!-- 配置c3p0数据源 -->
15     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
16         <property name="user" value="${user}"></property>
17         <property name="password" value="${password}"></property>
18         <property name="driverClass" value="${driverClass}"></property>
19         <property name="jdbcUrl" value="${jdbcUrl}"></property>
20         
21         <property name="initialPoolSize" value="${initPoolSize}"></property>
22         <property name="maxPoolSize" value="${maxPoolSize}"></property>
23     </bean>
24     
25     <!-- 配置自动扫描的包 -->
26     <context:component-scan base-package="spring"></context:component-scan>
27     
28     <!-- 配置spring 的JdbcTemplate -->
29     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
30         <property name="dataSource" ref="dataSource"></property>
31     </bean>
32 
33     <!-- 配置事务管理器 -->
34     <bean id="transactionManager" 
35     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
36         <property name="dataSource" ref="dataSource"></property>
37     </bean>
38     
39     <!-- 启用事务注解 -->
40     <tx:annotation-driven transaction-manager="transactionManager"/>
41     
42     
43 </beans>
applicationContext.xml

 配置文件jdbc.propertices:

user=root
password=123
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc\:mysql\:///spring?encoding\=UFT-8
initPoolSize=5
maxPoolSize=20

 

BookShopDao.java:

package spring.tx;

public interface BookShopDao {

    public int findBookPriceByIsbn(String isbn);
    public void updataBookStock(String isbn);
    public void updataUserAccount(String username,int price);
}

BookShopDaoImp.java:

技术分享
 1 package spring.tx;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.jdbc.core.JdbcTemplate;
 5 import org.springframework.stereotype.Repository;
 6 
 7 @Repository("bookShopDao")
 8 public class BookShopDaoImp implements BookShopDao {
 9 
10     @Autowired
11     private JdbcTemplate jdbcTemplate;
12 
13     @Override
14     public int findBookPriceByIsbn(String isbn) {
15         String sql = "select price from book where isbn=?";
16         return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
17     }
18 
19     @Override
20     public void updataBookStock(String isbn) {
21         // 检查书的库存是否不够
22         String sql1 = "select stock from book_stock where isbn=?";
23         if (jdbcTemplate.queryForObject(sql1, Integer.class, isbn) <= 0) {
24             throw new BookStockException("库存不足");
25         }
26         String sql = "update book_stock  set stock=stock-1 where isbn=?";
27         jdbcTemplate.update(sql, isbn);
28     }
29 
30     @Override
31     public void updataUserAccount(String username, int price) {
32         // 检查余额是否足够
33         String sql1 = "select balance from account where username=?";
34         if (jdbcTemplate.queryForObject(sql1, Integer.class, username) < price) {
35             throw new UserAccountException("余额不足");
36         }
37         String sql = "update account set balance = balance - ? where username=?";
38         jdbcTemplate.update(sql, price, username);
39     }
40 
41 }
BookShopDaoImp

BookShopService.java:

package spring.tx;

public interface BookShopService {
    public void purchase(String username,String isbn);
}

BookShopServiceImpl.java:

技术分享
 1 package spring.tx;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.jdbc.core.JdbcTemplate;
 5 import org.springframework.stereotype.Repository;
 6 
 7 @Repository("bookShopDao")
 8 public class BookShopDaoImp implements BookShopDao {
 9 
10     @Autowired
11     private JdbcTemplate jdbcTemplate;
12 
13     @Override
14     public int findBookPriceByIsbn(String isbn) {
15         String sql = "select price from book where isbn=?";
16         return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
17     }
18 
19     @Override
20     public void updataBookStock(String isbn) {
21         // 检查书的库存是否不够
22         String sql1 = "select stock from book_stock where isbn=?";
23         if (jdbcTemplate.queryForObject(sql1, Integer.class, isbn) <= 0) {
24             throw new BookStockException("库存不足");
25         }
26         String sql = "update book_stock  set stock=stock-1 where isbn=?";
27         jdbcTemplate.update(sql, isbn);
28     }
29 
30     @Override
31     public void updataUserAccount(String username, int price) {
32         // 检查余额是否足够
33         String sql1 = "select balance from account where username=?";
34         if (jdbcTemplate.queryForObject(sql1, Integer.class, username) < price) {
35             throw new UserAccountException("余额不足");
36         }
37         String sql = "update account set balance = balance - ? where username=?";
38         jdbcTemplate.update(sql, price, username);
39     }
40 
41 }
BookShopServiceImpl.java

 

Cashier.java:

package spring.tx;

import java.util.List;

public interface Cashier {
    public void checkout(String username,List<String> isbns); 
}

CashierImpl.java:

技术分享
 1 package spring.tx;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7 import org.springframework.transaction.annotation.Propagation;
 8 import org.springframework.transaction.annotation.Transactional;
 9 
10 @Service("cashier")
11 public class CashierImpl implements Cashier {
12 
13     @Autowired
14     private BookShopService bookShopService;
15     
16     
17     @Transactional
18     @Override
19     public void checkout(String username, List<String> isbns) {
20         for (int i = 0; i < isbns.size(); i++) {
21             bookShopService.purchase(username, isbns.get(i));
22         }
23     }
24 
25 }
CashierImpl

定义两个异常类:

技术分享
 1 package spring.tx;
 2 
 3 public class BookStockException extends RuntimeException{
 4 
 5     /**
 6      * 
 7      */
 8     private static final long serialVersionUID = 1L;
 9 
10     public BookStockException() {
11         super();
12         // TODO Auto-generated constructor stub
13     }
14 
15     public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
16         super(message, cause, enableSuppression, writableStackTrace);
17         // TODO Auto-generated constructor stub
18     }
19 
20     public BookStockException(String message, Throwable cause) {
21         super(message, cause);
22         // TODO Auto-generated constructor stub
23     }
24 
25     public BookStockException(String message) {
26         super(message);
27         // TODO Auto-generated constructor stub
28     }
29 
30     public BookStockException(Throwable cause) {
31         super(cause);
32         // TODO Auto-generated constructor stub
33     }
34 
35     
36 }
BookStockException
技术分享
package spring.tx;


public class UrAccountExceptionse extends RuntimeException {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public UserAccountException() {
        super();
        // TODO Auto-generated constructor stub
    }

    public UserAccountException(String message, Throwable cause, boolean enableSuppression,
            boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
        // TODO Auto-generated constructor stub
    }

    public UserAccountException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }

    public UserAccountException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public UserAccountException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

}
UserAccountExceptionse

测试方法:

package spring.tx.test;

import java.util.ArrayList;
import java.util.List;

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

import spring.tx.BookShopDao;
import spring.tx.BookShopService;
import spring.tx.Cashier;

public class SpringTransactionTest {

    private ApplicationContext ctx=null;
    private BookShopDao bookShopDao;
    private BookShopService bookShopService;
    private Cashier cashier;
    {
        ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        bookShopDao =(BookShopDao) ctx.getBean("bookShopDao");
        bookShopService=(BookShopService) ctx.getBean("bookShopService");
        cashier =(Cashier) ctx.getBean("cashier");
    }
    
    @Test
    public void testTransactionPropagation(){
        List<String > isbns=new ArrayList<String>();
        isbns.add("1001");
        isbns.add("1002");
        cashier.checkout("aaa", isbns);
    }
    
    @Test
    public  void testBookShopService() {
         bookShopService.purchase("aaa", "1001");
    }
    
    @Test
    public void testupdataBookStock(){
        bookShopDao.updataBookStock("1001");
    }
    
    @Test
    public void testUpdataUserAccount(){
        bookShopDao.updataUserAccount("aaa", 200);
    }
    
    @Test
    public void testBookShopDao(){
        int price=bookShopDao.findBookPriceByIsbn("1001");
        System.out.println(price);
    
    }
}

 

Spring初学之spring的事务管理注解