spring 事务传播问题

工作中碰到的一个小问题:

背景:

方法1、2 均在spring aop事务管理下

现执行结果: 方法2抛异常,方法2回滚,方法1也回滚了

期望结果:方法2抛异常,方法2回滚,方法1不回滚

 思考

spring事务什么时候会自动回滚?

Spring事务回滚机制是这样的:当所拦截的方法(@Transactional或者通过xml配置)有指定异常抛出,事务才会自动进行回滚! 

 异常抛出?

 即方法中出现的指定异常,只有在被事务管理器捕捉到以后,事务才会据此进行事务回滚

哪些异常会回滚?

默认Error与RuntimeException,不包括checkedException 如IOException

查看源码可知默认情况为这两种异常:

 有rollBackFor的情况,则根据设置的异常来定

由上述知识铺垫分析下问题,发现方法2抛出异常被catch住之后,正常情况下,不应该会导致方法1被回滚

再思考:

配置:

发现事务传播属性配置的

7种Propagation :

  • PROPAGATION_REQUIRED:默认事务类型,如果没有,就新建一个事务;如果有,就加入当前事务。适合绝大多数情况。
  • PROPAGATION_REQUIRES_NEW:如果没有,就新建一个事务;如果有,就将当前事务挂起。
  • PROPAGATION_NESTED:如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。
  • PROPAGATION_SUPPORTS:如果没有,就以非事务方式执行;如果有,就使用当前事务。
  • PROPAGATION_NOT_SUPPORTED:如果没有,就以非事务方式执行;如果有,就将当前事务挂起。即无论如何不支持事务。
  • PROPAGATION_NEVER:如果没有,就以非事务方式执行;如果有,就抛出异常。
  • PROPAGATION_MANDATORY:如果没有,就抛出异常;如果有,就使用当前事务。

由于add*方法是默认的required,所以方法2的事务应该是:

方法2的父方法有事务,故加入其事务。

当其抛出异常时,符合spring事务回滚的条件,故回滚该事务

结论:

如果想要达到目的,只需要将方法2的事务传播属性改为PROPAGATION_NESTED即可

猜你喜欢

转载自blog.csdn.net/Jesse_cool/article/details/88548446