关于Spring事务嵌套回滚的一些测试总结(精简)

前言

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

场景前提

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

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

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


场景一

A,B都使用事务注解:@Transactional(rollbackFor = Exception.class),

测试条件结果
B发生异常,A未catchA回滚,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未catchA回滚,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未catchA不回滚,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未catchA不回滚,B回滚
B发生异常,Acatch了异常,记录日志,未抛出异常A不回滚,B回滚
B发生异常,Acatch了异常,记录日志,抛出异常A回滚,B回滚
B执行成功后,A发生了异常A回滚,B不回滚

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

即:AB属于两个独立的事务,互不影响。


以上均为个人测试后得到的结论,若有错误,请不吝指教。


[参考]:浅析Spring事务传播行为和隔离级别

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值