Spring 七种事务传播性介绍( 二 )


文章插图
如果 方法B 抛出异常后,方法A 使用 try-catch 处理了方法B的异常(如下代码),并没有向外抛出,此时事务又如何处理的 ?

Spring 七种事务传播性介绍

文章插图
方法A也会回滚 。
从事务的特性我们可知,事务具有原子性 。方法A和方法B同属一个事务,当方法B抛出异常,触发回滚操作后,整个事务的操作都会回滚 。
因此,Spring 在处理事务过程中 , 当事务的传播性设置为REQUIRED,在整个事务的调用链上,任何一个环节抛出的异常都会导致全局回滚 。
3.2 REQUIRES_ NEW每次都开启一 个新的事务 。
Spring 七种事务传播性介绍

文章插图
 例子:
Spring 七种事务传播性介绍

文章插图
上面例子中,方法B的传播性设置为 REQUIRES_NEW,方法A仍然是REQUIRED,当A调用B时,具体调用链路如下:
Spring 七种事务传播性介绍

文章插图
具体执行过程:
  • 方法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接收到异常,导致回滚 。
Spring 七种事务传播性介绍

文章插图
3.3  SUPPORTED当外层方法A存在事务,方法B加入到当前事务中,以事务的方式执行 。
Spring 七种事务传播性介绍

文章插图
当外层方法A不存在事务,方法B不会创建新的事务 , 以非事务的方式执行 。
Spring 七种事务传播性介绍

文章插图
 例子1:
Spring 七种事务传播性介绍

文章插图

Spring 七种事务传播性介绍

文章插图
以上例子,方法A没有加事务注解,方法B的加了事务注解,并且传播为SUPPORTS 。
具体执行过程:
  • 方法A以非事务的方式执行insert操作 。
  • 方法B被调用,由于其外层事务A没有开启事务,方法B也是以非事务方法执行insert操作 。

Spring 七种事务传播性介绍

文章插图
例子2:
Spring 七种事务传播性介绍

文章插图
以上例子,方法A和B都加上了事务注解,其中方法A的传播性为REQUIRED,方法B的传播性为SUPPORTS 。
具体执行过程:
  • 如果方法A的调用方没有开启事务,则方法A开启事务,并执行insert操作,但没有提交;
  • 方法B被调用 , 由于其外层方法A开启了事务,因此方法B加入到方法A开启的事务中,并执行insert,但没有提交;
  • 当事务中的所有操作执行成功后,事务提交 。

Spring 七种事务传播性介绍

文章插图
3.4  NOT_SUPPORTED不支持事务 。
如果外层方法存在事务,则挂起外层事务,以非事务方式执行 , 执行完毕后 , 恢复外层事务 。
Spring 七种事务传播性介绍

文章插图
例子:
Spring 七种事务传播性介绍

文章插图
以上例子:方法A和B都加上了事务注解 , 方法A的传播性为REQUIRED,方法B为NOT_SUPPORTED 。
具体执行过程: