本文主要介绍了Spring事务传播性的相关知识 。
Spring中定义了7种事务传播性:
- PROPAGATION_REQUIRED
- PROPAGATION_SUPPORTS
- PROPAGATION_MANDATORY
- PROPAGATION_REQUIRES_NEW
- PROPAGATION_NOT_SUPPORTED
- PROPAGATION_NEVER
- PROPAGATION_NESTED
一、什么是Spring事务的传播性Spring 事务传播性是指 , 在Spring的环境中,当多个含有事务的方法嵌套调用时,每个事务方法都处于自己事务的上下文中,其提交或者回滚行为应该如何处理 。
通俗讲,就是当一个事务方法调用另外一个事务方法时 , 事务如何跨上下文传播 。
文章插图
1)当事务方法A调用事务方法B时,事务方法B是合并到事务方法A中,还是开启新事务?
2)当事务方法B抛出异常时 , 在合并事务或者开启新的事务的场景中 , 事务的回滚是如何处理的 ?
以上事务的处理规则,都取决于事务传播级别的设置 。
二、事务的传播性都有哪些行为
文章插图
事务的传播行为,主要分为三种类型,分别是:支持当前事务、不支持当前事务、嵌套事务 。
2.1 支持当前事务REQUIRED:默认的事务传播级别,表示如果当前方法已在事务内 , 该方法就在当前事务中执行,否则,开启一个新的事务并在其上下文中执行 。
SUPPORTED:当前方法在事务内 , 则在其上下文中执行该方法,否则,开启一个新的事务 。
MANDATORY:必须在事务中执行 , 否则 , 将抛出异常 。
2.2 不支持当前事务REQUIRES_NEW:无论当前是否有事务上下文,都会开启一个事务 。如果已经有一个事务在执行 ,则正在执行的事务将被挂起 , 新开启的事务会被执行 。
事务之间相互独立,互不干扰 。
NOT_SUPPORTED:不支持事务,如果当前存在事务上下文 , 则挂起当前事务,然后以非事务的方式执行 。
NEVER:不能在事务中执行,如果当前存在事务上下文,则抛出异常 。
2.3 嵌套事务NESTED:嵌套事务,如果当前已存在一个事务的上下文中,则在嵌套事务中执行,如果抛异常,则回滚嵌套事务,而不影响其他事务的操作 。
三、每种事务的传播性如何工作3.1 REQUIRED 默认的事务传播行为 , 保证多个嵌套的事务方法在同一个事务内执行 , 并且同时提交,或者出现异常时 , 同时回滚 。
这个机制可以满足大多数业务场景 。
文章插图
例子 :
文章插图
文章插图
图片
1)类TestAService的方法通过声明式事务的方式,加上了事务注解@Transactional , 并设置事务的传播性为REQUIRED 。
2)调用者调用TestAService的A方法时,如果调用者没有开启事务,那么A方法会开启一个事务 。
A方法的具体执行过程如下 :
a. 执行insert,但没有提交;
b.调用TestBServcie的B方法,由于B方法也声明了事务,并且传播性是REQUIRED,所以方法B的事务,合并到方法A开启的事务中 。
c.方法B执行insert操作,此时也没有提交 。
3)由于这两个方法的操作都在同一个事务中执行,当这两个方法所有操作执行成功之后,提交事务 。
嵌套调用链路:
文章插图
当方法B 执行时抛出了 Exception 异常后,事务是如何处理的 ?
1)方法B声明了事务,insert操作会回滚
2)由于方法A和方法B 同属一个事务,方法A也会执行回滚,由此说明该规则保证了事务的原子性 。
嵌套调用,异常后的链路:
推荐阅读
- 炒面筋的家常做法,油面筋最好吃的七种家常做法
- 简易版的SpringBoot是如何实现的!!!
- Spring非常实用的技巧,你确定知道?
- 分布式场景下的事务机制
- SpringBoot中如何优雅地个性化定制Jackson
- 监控 Spring Cloud 微服务的实践方案
- 解析MongoDB的并发控制和事务隔离级别:保证数据一致性
- SpringBoot+虚拟线程,接口吞吐量成倍增加,太爽了!
- springboot-如何集成Validation进行参数校验
- Spring6提供的四种远程接口调用神器!你知道那种?