• (VI)事务:Spring 事务案例


    一、测试数据准备

      1、需求

        

      2、数据表

    CREATE TABLE book (
      isbn VARCHAR (50) PRIMARY KEY,
      book_name VARCHAR (100),
      price INT
    ) ;
    
    CREATE TABLE book_stock (
      isbn VARCHAR (50) PRIMARY KEY,
      stock INT,
      CHECK (stock > 0)
    ) ;
    
    CREATE TABLE account (
      username VARCHAR (50) PRIMARY KEY,
      balance INT,
      CHECK (balance > 0)
    ) ;
    
    INSERT INTO account (`username`,`balance`) VALUES ('Tom',100000);
    INSERT INTO account (`username`,`balance`) VALUES ('Jerry',150000);
    
    INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-001','book01',100);
    INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-002','book02',200);
    INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-003','book03',300);
    INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-004','book04',400);
    INSERT INTO book (`isbn`,`book_name`,`price`) VALUES ('ISBN-005','book05',500);
    
    INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-001',1000);
    INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-002',2000);
    INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-003',3000);
    INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-004',4000);
    INSERT INTO book_stock (`isbn`,`stock`) VALUES ('ISBN-005',5000);

    二、环境搭建

      在配置文件中配置数据源和 JdbcTemplate:

        <context:component-scan base-package="com.njf.tx"></context:component-scan>
    
        <context:property-placeholder location="db.properties"></context:property-placeholder>
    
        <!--  配置数据源  -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="user" value="${jdbc.user}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
            <property name="driverClass" value="${jdbc.driverClass}"></property>
        </bean>
        
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>

    三、业务代码

      BookDao:

    @Repository
    public class BookDao {
    
    
        @Autowired
        JdbcTemplate jdbcTemplate;
    
        /**
         * 1、减余额
         *
         * 减去用户的余额
         */
        public void updateBalance(String userName, int price) {
            String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";
            int i = jdbcTemplate.update(sql,price, userName);
        }
    
        /**
         * 2. 获取某本图书的价格
         * @return
         */
        public int getPrice(String isbn) {
            String sql = "SELECT price FROM book WHERE isbn = ?";
            return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
        }
    
        /**
         * 3. 减去对应图书的库存,每次减1
         */
        public void updateStock(String isbn) {
            String sql = "UPDATE book_stock SET stock = stock - 1 WHERE isbn = ?";
            jdbcTemplate.update(sql,isbn);
        }
    }

      BookService:

    @Service
    public class BookService {
    
        @Autowired
        private BookDao bookDao;
    
        /**
         * 结账,哪个用户买了哪本书
         * @param userName
         * @param isbn
         */
        public void checkOut(String userName, String isbn) {
            bookDao.updateStock(isbn);
    
            int price = bookDao.getPrice(isbn);
    
            bookDao.updateBalance(userName, price);
        }
    }

      测试:

    public class TxTest {
    
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
        @Test
        public void test() {
            BookService bookService = ioc.getBean(BookService.class);
    
            bookService.checkOut("Tom", "ISBN-001");
    
            System.out.println("结账完成");
        }
    }

    四、添加事务管理

      1、配置事务管理器

        <!--1: 配置事务管理器让其进行事务控制-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!--控制住数据源-->
            <property name="dataSource" ref="dataSource"></property>
        </bean>

      2、开启基于注解的事务控制

        <!-- 2: 开启基于注解的事务控制模式:依赖 tx 名称空间  -->
        <tx:annotation-driven transaction-manager="transactionManager" />

      3、给事务方法加注解

        @Transactional
        public void checkOut(String userName, String isbn) {
            bookDao.updateStock(isbn);
    
            int price = bookDao.getPrice(isbn);
    
            int i = 10 / 0;
    
            bookDao.updateBalance(userName, price);
    
        }

      测试:当给加了@Transactional 方法的内部手动制造异常情况,整个操作都会回滚,满足事务的要求。

  • 相关阅读:
    css下背景渐变与底部固定的蓝天白云
    indy10中idtcpclient的使用问题[和大华电子称数据交换]
    cliendataset中自增长字段的处理
    和大华电子称进行对数据通讯
    cxgrid主从表的困惑
    基于xml基类的web查询
    关于屏幕文件
    基于xml文件查询的xml文件之生成篇
    关于400改程序
    Tapestry Spring Hibernate整合工作小结[摘]
  • 原文地址:https://www.cnblogs.com/niujifei/p/15489658.html
Copyright © 2020-2023  润新知