Spring事务传播性的相关知识

作者:vivo 互联网服务器团队 - zhou shaobin
本文主要介绍了spring事务传播性的相关知识。
spring中定义了7种事务传播性:
propagation_required 
propagation_supports
propagation_mandatory
propagation_requires_new
propagation_not_supported
propagation_never
propagation_nested
在spring环境中,含有事务的方法嵌套调用,事务是如何传递的规则,以及每种规则是如何开展工作的。文章还提到每种事务传播性是如何使用的,方便读者依据实际的场景,使用不同的事务规则。
一、什么是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也会执行回滚,由此说明该规则保证了事务的原子性。
嵌套调用,异常后的链路:
如果 方法b 抛出异常后,方法a 使用 try-catch 处理了方法b的异常(如下代码),并没有向外抛出,此时事务又如何处理的 ?
方法a也会回滚。
从事务的特性我们可知,事务具有原子性。方法a和方法b同属一个事务,当方法b抛出异常,触发回滚操作后,整个事务的操作都会回滚。
因此,spring 在处理事务过程中,当事务的传播性设置为required,在整个事务的调用链上,任何一个环节抛出的异常都会导致全局回滚。
3.2 requires_ new
每次都开启一 个新的事务。
例子:
上面例子中,方法b的传播性设置为 requires_new,方法a仍然是required,当a调用b时,具体调用链路如下:
具体执行过程:
方法a被执行前,如果调用者没有开启事务,方法a开启一个事务1,然后执行insert ,此时没有提交;
方法b的事务传播性设置为requires_new,当被方法a调用时,此时方法a的事务1会被挂起,方法b开启自己的事务2,然后执行insert,此时并没有提交;
当方法b执行完毕后,提交事务2;
恢复事务1,最终提交。
当 方法b 执行时抛出了异常,会发生什么?
方法b的insert操作会被回滚掉,方法a不受影响。但这里有个前提,方法a需要try-catch方法b的异常,使其异常不会往上传递,从而导致方法a接收到异常,导致回滚。
3.3  supported
当外层方法a存在事务,方法b加入到当前事务中,以事务的方式执行。
当外层方法a不存在事务,方法b不会创建新的事务,以非事务的方式执行。
例子1:
以上例子,方法a没有加事务注解,方法b的加了事务注解,并且传播为supports。
具体执行过程:
方法a以非事务的方式执行insert操作。
方法b被调用,由于其外层事务a没有开启事务,方法b也是以非事务方法执行insert操作。
例子2:
以上例子,方法a和b都加上了事务注解,其中方法a的传播性为required,方法b的传播性为supports。
具体执行过程:
如果方法a的调用方没有开启事务,则方法a开启事务,并执行insert操作,但没有提交;
方法b被调用,由于其外层方法a开启了事务,因此方法b加入到方法a开启的事务中,并执行insert,但没有提交;
当事务中的所有操作执行成功后,事务提交。
3.4  not_supported
不支持事务。
如果外层方法存在事务,则挂起外层事务,以非事务方式执行,执行完毕后,恢复外层事务。
例子:
以上例子:方法a和b都加上了事务注解,方法a的传播性为required,方法b为not_supported。
具体执行过程:
如a的调用方没有开启事务,方法a开启事务,并执行insert,但没有提交。
方法a调用方法b时,方法b的传播性为not_supported,不支持事务,然后挂起外层方法a的事务,方法b以非事务的方式执行insert。
方法b执行完毕后,恢复方法a的事务,最终提交事务。
调用链路过程:
3.5 never
不支持事务
当外层方法a开启了事务,方法b抛出异常
例子:
以上代码,两个方法都打上了事务注解,方法a的传播性是required,方法b的传播性是never。
具体执行过程:
方法a开启事务,执行insert,没有提交。
含有事务的方法a调用方法b,方法b的传播性是never,表示不支持事务,因此方法b抛出异常。
方法a的事务执行回滚。
3.6 mandatory
必须在事务中执行。
如果外层方法a没有开启事务,方法b抛出异常。
如果外层方法a开启了事务,方法b加入事务,方法a&b在同一事务中执行。
例子:
以上例子,方法a没有加事务注解,方法b 的传播性为 mandatory。
具体执行过程:
方法a的调用方如果本身没有开启事务,方法a执行前不会开启事务。
当非事务方法a调用方法b时,由于方法b的传播性为mandatory,必须在事务中执行,条件不满足,抛出异常。
3.7 nested
嵌套事务
如果外层方法a不存在事务,内层方法b的规则与required 一致。
如果外层方法a存在事务,内层方法b做为外层方法a事务的子事务执行,两个方法是一起提交,但子事务是独立回滚。
内层方法b抛出异常,则会回滚方法b的所有操作,但不影响外层事务方法a。(方法a需要try-catch子事务,避免异常传递到父层事务)
外层方法a回滚,则内层方法b也会回滚。
该传播性的特点是可以保存状态点,当回滚时,只会回滚到某一个状态点,保证了子事务之间的独立性,避免嵌套事务的全局回滚。
例子:
以上例子,方法a的传播性为required,方法b为nested。
具体执行过程:
方法a执行时,如调用方没有开启事务,则开启一个事务。
方法b被外层方法a调用时,因为方法b的传播性为nested,方法b在此处建立savepoint,标记insert行为。
当方法b抛出异常,其insert操作会回滚,但只会回滚到savepoint,(前提是方法a要try-catch方法b,使方法b的异常不会往外传递)。
方法b回滚后,方法a的事务提交。
调用链路:
四、总结
本文解释了spring框架中的事务传播性,即多个业务方法之间调用时事务如何处理的规则。spring提供了七种传播级别,如
propagation_required、
propagation_requires_new等。
每种级别都有适用场景和限制,本文提供了一些示例,介绍了声明式事务如何使用,每种事务的规则,产生哪种行为,当方法抛出异常时,事务的提交和回滚是如何被处理的。正确处理事务对于任何企业级应用程序都是必要的,了解spring事务传播性是构建高效、可靠和可扩展应用程序的关键。


ThermaSim在线MOSFET热仿真工具改进设计
江波龙电子获得海关AEO高级认证,将享受多项通关便利措施
基于IGBT电路的逆变器设计与分析,IGBT数字化模块设计与考量
物联网技术在智慧农业中的关健技术和主要应用
基于3GPP R15标准的电话正式打通,5G即将登台2G将全面退服
Spring事务传播性的相关知识
高频纯正逆变电源的安全与操作方法
不光是基带,相关的射频芯片和天线,苹果也要自研
为什么要促进动力电池产业发展?这几点值得思考
PICOCAP 测量原理展示了对于电容测量的新的革命性的方式
Aqara打造个性化全屋智能安防系统
电网设备和电力设备区别 电力网的主要设备有哪些
AI开发的最新技术;彭博让你节省不必要的时间
盘点未来智能网联汽车的发展趋势
Qorvo面向6GHz以下无线基础设施推出高能效、小基站的5G解决方案
关于贪心算法详解
DC-DC转换器原理及应用
hc32和gd32的区别
【10月17日|上海】2023 EDA用户创新论坛——技术盛会的序幕即将拉开
如何给iPhone6 Plus换上一个新屏?