@Transactional事务注解失效
事务注解失效可能出现在以下几个方面:
- @Transactional 标注在了非public修饰的方法上 ————事务注解失效
- @Transactional注解属性propagation设置错误—————事务注解失效
- PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
- @Transactional 注解属性 rollbackFor 设置错误——————事务注解失效
- rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定rollbackFor属性。
- 同一个类中方法调用,导致@Transactional失效
- 两个方法 A、B,其中B为被事务注解标注的方法,方法A会调用方法B这种情况——————事务注解失效(不论方法B使用public修饰还是private修饰),但方法A没有声明注解事务,而方法B有,则外部调用方法A之后,方法B的事务是不会起作用的
- 但如果使用代理类对象调用方法B那么方法B中的事务生效
- 异常被你的 catch“吃了”导致@Transactional失效——————事务注解失效
- 方法A、B,其中A,B都声明了事务,方法A在调用方法B的时候,方法B抛出异常需要回滚,但是方法A中使用了try…catch 进行了手动处理,这时B方法不再回滚
- 所以要想让事务生效需要在catch中重新抛出一个运行时异常, throw new RuntimeException或者注解中指定抛异常类型
- 数据库引擎不支持事务—————事务注解不生效
- 被外部调用的公共方法A有两个进行了数据操作的子方法B和子方法C的事务注解说明:
- 被外部调用的公共方法A未声明事务@Transactional,子方法B和C若是其他类的方法且各自声明事务,则事务由子方法B和C各自控制
- 被外部调用的公共方法A未声明事务@Transactional,子方法B和C若是本类的方法,则无论子方法B和C是否声明事务,事务均不会生效
- 被外部调用的公共方法A声明事务@Transactional,无论子方法B和C是不是本类的方法,无论子方法B和C是否声明事务,事务均由公共方法A控制
- 被外部调用的公共方法A声明事务@Transactional,子方法运行异常,但运行异常被子方法自己 try-catch 处理了,则事务回滚是不会生效的!