Bootstrap

@Transactional事务嵌套,失败情况分析

@Transactional事务失败情况分析

使用声明式注解事务,Spring扫描到带有@Transactional的方法,对其进行代理增强(AOP切面,调用方法前begin,方法结束后commit),当调用了一个未被增强的方法A(无事务注解),内部又调用了一个有事务注解的方法B,由于A是被代理的B并未被代理,所以B没有被增强(即使有事务),相反,如果代理了有事务注解的方法,那么内部无论是否有注解都会被事务包含在内。

个人理解,有不对的地方请帮忙矫正.

//伪代码
  Transactional.begin
  A(有事务,被增强) 内部调用-> B(无论有没有事务,在不在同一个类,都会被增强)
  Transactional.commit

  A(无事务) 内部调用->B(同类B不增强(未被代理),不同类B会被增强(被代理),A不会)

第一种情况

同一个类A调用B在都有事务的情况下,B出错,AB全部回滚,事务成功
在这里插入图片描述

第二种情况

同一个类,去掉外层A的事务,B依然有事务,B事务未生效,name成功被修改为22222。

相反去掉内层B的事务开启外层A的事务,事务成功
在这里插入图片描述
结合第一第二种情况来讲,只要最外层有事务,内部不需要加不加事务都会被外层影响,内部如果出错整体都会回滚

第三种情况

这种情况下,在test2事务顺利的情况下,B抛异常,无外层事务,name被修改为22222。

如果test2抛出了异常,在外层无事务的情况下,name被修改为了11111,B并未被调用。
在这里插入图片描述

第四种情况

外层有事务,test2中无事务且抛异常,B未被执行,事务成功,完成回滚
在这里插入图片描述
总结一下就是,
1.当在同一个类中 外层有事务的情况下,内层无论是否加事务,事务都会成功
2.当在同一个类中外层无事务的情况下,内层无论是否有事务,事务都会失败
3.当在不同类中 外层有事务的情况下,内层无论是否有事务,事务都会成功
4.当在不同类中外层无事务的情况下,内层有事务,内层回滚,外层事务失败

;