天天看点

@Transactional解析

不生效的情况

  • 首先@Transactional注解在私有方法上不生效

    ​​

    ​原因是生成的代理类访问不到私有方法,所以不会生效​

  • 如果Spring项目没有开启事务,就是在某个配置类上增加@EnableTransactionManagement开启事务管理的注解,那么也会失效。或者在Spring容器中手动创建事务管理器这个Bean

    ​​

    ​SpringBoot在@SpringBootApplication注解中开启了事务管理,它的实现原理是去读取spring.factories文件,它会自动加载一些启动类,其中就包含了事务管理启动类​

  • 抛出的异常不是Error与RuntimeException,而是非运行时异常

    ​​

    ​默认回滚 Error与 RuntimeException运行时异常​

  • 异常被内部捕获了
  • A方法内部调用了B方法,而且B方法也加了事务注解,这种情况也是不会回滚的。
  • 数据库引擎不支持事务,目前常见的InnoDB是支持的

原理分析

public abstract class TransactionAspectSupport ...{

  protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
      final InvocationCallback invocation) throws Throwable {
    ....
    try {
      // 这里最终会调用到目标方法
      retVal = invocation.proceedWithInvocation();
    } catch (Throwable ex) {
      // 目标方法抛出了异常,根据@Transactional注解属性配置决定是否需要回滚事务
      completeTransactionAfterThrowing(txInfo, ex);
      throw ex;
    }
    ...
        //目标方法正常执行完成,提交事务
    commitTransactionAfterReturning(txInfo);
    ....
}