Spring事务传播
PROPAGATION_NESTED
- 共用一个事务,但每一层都有独立的保存点,可以独立提交事务的回滚。
- 每层事务可以通过TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 独立设置是否回滚。当前层的回滚不会影响上层的回滚,但上层的回滚会影响下层的回滚。
- 如果是通过抛出异常导致的回滚,这个会触发整个事务的回滚(Sping的事务处理中异常的回滚处理和手动回滚走的不同的处理逻辑)。
如果下层回滚,最上层不回滚,则最终事务仍是作为正常提交成功的事务,仍会触发事务提交成功后的事件,并不会触发事务回滚的事件。即最终事务的状态由最顶层的事务决定。
PROPAGATION_REQUIRED
共用一个事务,只能设置全局回滚或全局不回滚,不支持局部回滚。
- 如果有多层,只要有任意一层设置了回滚,则它的上一层及最上层也必须设置回滚,否则会抛出Transaction rolled back because it has been marked as rollback-only异常。
由于所有层都是统一的提交和回滚,因此不会出现部分提交的问题。
@Transactional
除非特殊配置(比如使用 AspectJ 静态织入实现 AOP),否则只有定义在 public 方法上的 @Transactional 才能生效
原因是,Spring 默认通过动态代理的方式实现 AOP,对目标方法进行增强,private 方法无法代理到, Spring 自然也无法动态增强事务处理逻辑。
- 必须通过代理过的类从外部调用目标方法才能生效
- 只有异常传播出了标记了 @Transactional 注解的方法,事务才能回滚
- 默认情况下,出现 RuntimeException(非受检异常)或 Error 的时候,Spring才会回滚事务
- 注意事务传播配置符合业务逻辑