场景```
1. 事务方法不是public修饰的,将会导致事务失效
2. 事务方法使用了final或static修饰,将会导致事务失效
3. 方法内部之间调用,没有通过代理对象调用
4. 未被spring容器管理,方法不会产生事务
5. 多线程调用dao方法
6. 表不支持事务
7. 未开启事务
8. 使用了错误的事务传播行为
9. 自己吞了异常
10. 抛出了编译时异常
11. 自定义了指定异常类(rollbackFor属性)回滚,但实际发生的异常类与指定的异常类不一致
12. 事务回滚多了
细节(和上面每一条一一对应):
1. AbstractFallbackTransactionAttributeSource类中的computeTransactionAttribute方法中只规定了public修饰的方法才可以
2. spring事务底层使用了AOP,而AOP的底层是动态代理,动态代理分为两种:1,JDK自带的动态代理,需要被代理类实现接口,2,基于cglib的动态代理,需要继承被代理类,final修饰的方法不能被重写,所以会导致final修饰的方法事务失效
3. 方法拥有事务能力是因为使用了代理对象的方法
4. 没有使用@Service注解交给spring容器管理
5. 不同线程获取到的数据库连接不一样,从而是两个不同的事务,spring事务是通过数据库连接来实现的(ThreadLocal),同一个数据库连接才可以同时提交和同时回滚
6. 例如mysql的表使用了myisam引擎
7. 非springboot项目,例如传统spring项目,需要配置事务管理器开启事务
8. @Transactional注解的propagation为NEVER(方法不支持事务)
9. 使用了try、catch捕获了异常而没有抛出异常,事务不会回滚,spring会认为程序是正常的
10. spring事务默认支持运行时异常的回滚,如果开发人员自己捕获并在catch里抛出了编译时异常,则不会回滚
11. 自定义了指定异常(rollbackFor属性)回滚,但实际发生的异常与指定的异常不一致
12. 一个方法内有两个事务方法调用a(),b(),其中b方法出现了异常,导致b方法向上抛出异常,使得a方法也跟着回滚了导致a方法事务失效