随笔 - 1162  文章 - 0  评论 - 16  阅读 - 59万 

一、测试数据准备

  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 方法的内部手动制造异常情况,整个操作都会回滚,满足事务的要求。

 

posted on   格物致知_Tony  阅读(75)  评论(0编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?
点击右上角即可分享
微信分享提示

目录导航