[转]关于Spring事务嵌套回滚的一些测试总结

前言

这是我在spring事务中遇到关于事务嵌套问题的一些记录总结。
场景前提

测试数据库:sql server
A类的service A方法调用B类的service B方法;

ServiceA {
     void methodA() {
         ServiceB.methodB();
     }
}
ServiceB {
     void methodB() {
     }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9

注意:spring的@transactional只会对运行时异常捕获,并进行回滚,
若想所有异常都回滚,则使用@Transactional(rollbackFor = Exception.class)
默认事务传播行为:Propagation=PROPAGATION_REQUIRED
场景一

A,B都使用事务注解:@Transactional(rollbackFor = Exception.class),
测试条件     结果
B发生异常,A未catch     A回滚,B回滚
B发生异常,Acatch了异常,记录日志,未抛出异常     A回滚,B回滚,但出现了异常(Transaction rolled back because it has been marked as rollback-only)
B发生异常,Acatch了异常,记录日志,抛出异常     A回滚,B回滚
B执行成功后,A发生异常     A回滚,B回滚

结论:A,B只要有一个发生异常,A和B都会回滚
场景二

A使用事务注解:@Transactional(rollbackFor = Exception.class),B不使用事务;
测试条件     结果
B发生异常,A未catch     A回滚,B回滚
B发生异常,Acatch了异常,记录日志,未抛出异常     A,B都不回滚
B发生异常,Acatch了异常,记录日志,抛出异常     A回滚,B回滚
B执行成功后,A发生了异常     A回滚,B回滚

结论:只要A发生异常,A,B都回滚;B发生异常,若A catch了异常,但没有将异常抛出,则A,B都不回滚;除此之外,A,B都回滚
场景三(一般不用)

A不使用事务,B使用事务注解:@Transactional(rollbackFor = Exception.class)
测试条件     结果
B发生异常,A未catch     A不回滚,B回滚
B发生异常,Acatch了异常,记录日志,未抛出异常     A不回滚,B回滚
B发生异常,Acatch了异常,记录日志,抛出异常     A不回滚,B回滚
B执行成功后,A发生了异常     A,B都不回滚

结论:无论AB是否发生异常,A都不回滚;只有B发生异常,B才会回滚
场景四

A使用默认事务注解:@Transactional(rollbackFor = Exception.class)
B使用新事务注解:@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
测试条件     结果
B发生异常,A未catch     A不回滚,B回滚
B发生异常,Acatch了异常,记录日志,未抛出异常     A不回滚,B回滚
B发生异常,Acatch了异常,记录日志,抛出异常     A回滚,B回滚
B执行成功后,A发生了异常     A回滚,B不回滚

结论:A发生异常,只有A回滚,B不回滚;B发生异常,只有B回滚,A不回滚

即:AB属于两个独立的事务,互不影响。
————————————————
版权声明:本文为CSDN博主「iSteinsGate」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39911952/article/details/94406003

原文地址:https://www.cnblogs.com/use-D/p/12571839.html