Spring 全家桶之 Spring Framework 5.3(七)- 声明式事务(二)

简介: Spring 全家桶之 Spring Framework 5.3(七)- 声明式事务

三、声明式事务

声明式事务:以前通过复杂编程来编写一个事务,替换为只需要告诉Spring哪个方法是事务方法即可,由Spring进行事务控制,基于Spring AOP环绕通知。

事务管理器代码的固定模式作为一种横切关注点,可以通过Spring AOP方法模块化,借助Spring AOP框架实现生命是事务管理,事务切面即事务管理器

不同的数据库连接使用不同的事务管理器

xml中配置事务管理器,导入tx名称空间xmlns:tx="www.springframework.org/schema/tx"

<!--事务管理器配置-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启基于注解的配置模式-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
复制代码

验证事务

在BookService的checkout方法中增加异常代码

public void checkout(String username, String isbn){
    // 1.减库存
    bookDao.updateStock(isbn);
    // 异常代码
    System.out.println(10/0);
    // 2.减余额
    int price = bookDao.getPrice(isbn);
    bookDao.updateBalance(username,price);
}
复制代码

执行测试方法,检查数据库,库存被扣减1,而余额没有变化

image.png

将库存恢复至1000,余额恢复至10000,在checkout方法上增加@Transactional注解,再次测试 控制台报错,余额和库存数量没有变化,删除checkout方法中的异常代码,再次进行测试。

image.png

均可以正常扣减

四、@Transactional注解

@Transactional注解的属性

image.png

  • isolation:设置事务隔离级别
  • propagation:设置事务传播行为
  • noRollbakcFor:设置哪些异常事务不回滚,指定异常的class,是一个数组
  • noRollbackForClassName:设置哪些事务不回滚,指定异常的全类名,是一个数组
  • rollbackFor:设置哪些异常事务回滚,指定异常的class,是一个数组
  • rollbackForClassName:设置哪些异常事务回滚,指定异常的全类名,是一个数组
  • readOnly:布尔类型,设置事务为只读事务
  • timeout:超时时间,事务执行时间超出设定的时间自动终止并回滚

timeout

int类型,单位是秒,超时时间,事务执行超过指定的时间会自动停止并回滚

@Transactional(timeout = 3)
public void checkout(String username, String isbn){
    // 1.减库存
    bookDao.updateStock(isbn);
    // 休眠5s
    try {
        Thread.sleep(5000);
    } catch (Exception e){
        e.printStackTrace();
    }
    // 2.减余额
    int price = bookDao.getPrice(isbn);
    bookDao.updateBalance(username,price);
}
复制代码

执行测试方法,库存数和余额数无变化

readOnly

默认为false,readOnly=true可以设置事务为只读事务,实现对事务进行优化,提高查询速度,忽略事务的commit等操作

@Transactional(readOnly = true)
public void checkout(String username, String isbn){
    // 1.减库存
    bookDao.updateStock(isbn);
    // 2.减余额
    int price = bookDao.getPrice(isbn);
    bookDao.updateBalance(username,price);
}
复制代码

执行测试方法

image.png

事务中有更新操作,是不能设置readOnly的

noRollbackFor 和 noRollbackForClassName

  • 运行时异常,可以不用处理,默认都回滚
  • 编译时异常,使用try-catch处理或者在方法上声明throws,默认不回滚

noRollbackFor可以配置指定异常不回滚,即让原来默认回滚的异常不回滚 noRollbackForClassName指定不回滚的异常的全类名,noRollbackFor指定的是异常的类型,它们都是数组

//@Transactional(noRollbackForClassName = {"java.lang.ArithmeticException"})
@Transactional(noRollbackFor = {ArithmeticException.class})
public void checkout(String username, String isbn) {
    // 1.减库存
    bookDao.updateStock(isbn);
    // 2.减余额
    int price = bookDao.getPrice(isbn);
    bookDao.updateBalance(username, price);
    // 增加运行时异常,默认回滚
    System.out.println(10 / 0);
}
复制代码

将stock恢复至1000,余额恢复至10000,执行测试

image.png

余额和库存都进行了扣减,实现了让原本默认回滚的不回滚

rollBackFor 和 rollBackForClassName

指定让原本不回滚的异常回滚,所有的编译时异常默认不会滚

// @Transactional(rollbackForClassName = {"java.io.FileNotFoundException"})
@Transactional(rollbackFor = {FileNotFoundException.class})
public void checkout(String username, String isbn) throws FileNotFoundException {
    // 1.减库存
    bookDao.updateStock(isbn);
    // 2.减余额
    int price = bookDao.getPrice(isbn);
    bookDao.updateBalance(username, price);
    // 增加编译时异常,默认不回滚
    new FileInputStream("../stark.txt");
}
复制代码

将stock恢复至1000,余额恢复至10000,执行测试

image.png

余额和库存没有变化


相关文章
|
3月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
4月前
|
Java 关系型数据库 MySQL
Spring 事务失效场景总结
Spring 事务失效场景总结
64 4
|
15天前
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
31 1
Spring高手之路24——事务类型及传播行为实战指南
|
9天前
|
XML Java 数据库连接
Spring中的事务是如何实现的
Spring中的事务管理机制通过一系列强大的功能和灵活的配置选项,为开发者提供了高效且可靠的事务处理手段。无论是通过注解还是AOP配置,Spring都能轻松实现复杂的事务管理需求。掌握这些工具和最佳实践,能
15 3
|
2月前
|
Java 数据库连接 数据库
spring复习05,spring整合mybatis,声明式事务
这篇文章详细介绍了如何在Spring框架中整合MyBatis以及如何配置声明式事务。主要内容包括:在Maven项目中添加依赖、创建实体类和Mapper接口、配置MyBatis核心配置文件和映射文件、配置数据源、创建sqlSessionFactory和sqlSessionTemplate、实现Mapper接口、配置声明式事务以及测试使用。此外,还解释了声明式事务的传播行为、隔离级别、只读提示和事务超时期间等概念。
spring复习05,spring整合mybatis,声明式事务
|
2月前
|
Java 测试技术 数据库
Spring事务传播机制(最全示例)
在使用Spring框架进行开发时,`service`层的方法通常带有事务。本文详细探讨了Spring事务在多个方法间的传播机制,主要包括7种传播类型:`REQUIRED`、`SUPPORTS`、`MANDATORY`、`REQUIRES_NEW`、`NOT_SUPPORTED`、`NEVER` 和 `NESTED`。通过示例代码和数据库插入测试,逐一展示了每种类型的运作方式。例如,`REQUIRED`表示如果当前存在事务则加入该事务,否则创建新事务;`SUPPORTS`表示如果当前存在事务则加入,否则以非事务方式执行;`MANDATORY`表示必须在现有事务中运行,否则抛出异常;
143 4
Spring事务传播机制(最全示例)
|
1月前
|
Java 关系型数据库 MySQL
Spring事务失效,我总结了这7个主要原因
本文详细探讨了Spring事务在日常开发中常见的七个失效原因,包括数据库不支持事务、类不受Spring管理、事务方法非public、异常被捕获、`rollbackFor`属性配置错误、方法内部调用事务方法及事务传播属性使用不当。通过具体示例和源码分析,帮助开发者更好地理解和应用Spring事务机制,避免线上事故。适合所有使用Spring进行业务开发的工程师参考。
32 2
|
1月前
|
Java 程序员 Spring
Spring事务的1道面试题
每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。
Spring事务的1道面试题
|
2月前
|
Java Spring
Spring 事务传播机制是什么?
Spring 事务传播机制是什么?
23 4
|
1月前
|
监控 Java 数据库
Spring事务中的@Transactional注解剖析
通过上述分析,可以看到 `@Transactional`注解在Spring框架中扮演着关键角色,它简化了事务管理的复杂度,让开发者能够更加专注于业务逻辑本身。合理运用并理解其背后的机制,对于构建稳定、高效的Java企业应用至关重要。
56 0
下一篇
无影云桌面