前言
这是我在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