Spring事务传播

PROPAGATION_NESTED
  1. 共用一个事务,但每一层都有独立的保存点,可以独立提交事务的回滚。
  2. 每层事务可以通过TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 独立设置是否回滚。当前层的回滚不会影响上层的回滚,但上层的回滚会影响下层的回滚。
  3. 如果是通过抛出异常导致的回滚,这个会触发整个事务的回滚(Sping的事务处理中异常的回滚处理和手动回滚走的不同的处理逻辑)。
  4. 如果下层回滚,最上层不回滚,则最终事务仍是作为正常提交成功的事务,仍会触发事务提交成功后的事件,并不会触发事务回滚的事件。即最终事务的状态由最顶层的事务决定。

    PROPAGATION_REQUIRED
  5. 共用一个事务,只能设置全局回滚或全局不回滚,不支持局部回滚。

  6. 如果有多层,只要有任意一层设置了回滚,则它的上一层及最上层也必须设置回滚,否则会抛出Transaction rolled back because it has been marked as rollback-only异常。
  7. 由于所有层都是统一的提交和回滚,因此不会出现部分提交的问题。

    @Transactional

  8. 除非特殊配置(比如使用 AspectJ 静态织入实现 AOP),否则只有定义在 public 方法上的 @Transactional 才能生效

原因是,Spring 默认通过动态代理的方式实现 AOP,对目标方法进行增强,private 方法无法代理到, Spring 自然也无法动态增强事务处理逻辑。

  1. 必须通过代理过的类从外部调用目标方法才能生效
  2. 只有异常传播出了标记了 @Transactional 注解的方法,事务才能回滚
  3. 默认情况下,出现 RuntimeException(非受检异常)或 Error 的时候,Spring才会回滚事务
  4. 注意事务传播配置符合业务逻辑