Transactional 失效的4种场景
一、当有@Transactional 的方法被 没有@Transactional 注解方法调用时,注解@Transactional 方法会失效
public class Test { public void testA(){ new Test2().testB(); } } class Test2{ @Transactional public void testB(){ } }
二、注解在非public方法上会失效
原因:
是应为在Spring AOP代理时,事务拦截器在目标方法前后进行拦截,DynamicAdvisedInterceptor
的intercept 方法会获取Transactional注解的事务配置信息,
因为在Spring AOP 代理时,如上图所示
TransactionInterceptor
(事务拦截器)在目标方法执行前后进行拦截,DynamicAdvisedInterceptor
(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy
的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource
的 computeTransactionAttribute
方法会间接调用 AbstractFallbackTransactionAttributeSource
的 computeTransactionAttribute
方法,这个方法会获取Transactional 注解的事务配置信息。他会首先校验事务方法的修饰符是不是public,不是 public则不会获取@Transactional 的属性配置信息三、Transactional 事务配置属性中的propagation 属性配置的问题。
当propagation属性配置为:
TransactionDefinition.PROPAGATION_SUPPORTS
:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 TransactionDefinition.PROPAGATION_NOT_SUPPORTED
:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER
:以非事务方式运行,如果当前存在事务,则抛出异常四、当调用方法和被调用方法再听一个类中,被调用方的@Transactional 注解失效
public class Test { @Transactional public void A() { try { this.B(); } catch (Exception e) { e.printStackTrace(); } } @Transactional public void B(){ } }