不生效的情况
-
首先@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);
....
}