• 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);
        
        }
    }
  • 相关阅读:
    用colorWithPatternImage设置view背景色太占内存,替代方法
    快捷键
    数组里面放入随机数
    Android图像处理之Bitmap类
    android屏幕适配_
    最火的Android开源项目
    boost 编译
    QTextEdit更改单个段落/块的字体
    自定义QMenu样式
    Qimage QBuffer
  • 原文地址:https://www.cnblogs.com/hyyq/p/6705626.html
Copyright © 2020-2023  润新知