1、private、final、static 方法
被 @Transactional 注解标注的方法的访问权限必须是 public;
被 @Transactional 注解标注的方法不能被 final、static 修饰,被标注的方法必须是可覆盖的。这是因为事务底层使用的是 aop,而 aop 使用的是代理模式。代理模式生成的代理类无法重写被 final、static 修饰的方法。而 private 方法对子类不可见。
2、非事务方法调用
非事务方法调用事务方法,事务方法会失效。
3、抛出的异常不在回滚范围内
默认情况下,Spring 事务只有遇到 RuntimeException 以及 Error 时才会回滚,在遇到检查型异常时是不会回滚的,比如 IOException、TimeoutException。所以,一般情况下都需要使用 rollbackFor参数指定回滚异常类,比如:@Transactional(rollbackFor = Exception.class)
4、使用错误的传播行为
如果使用了 NOT_SUPPORTED 的传播行为,该行为的特性是:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
5、多线程调用
这是因为 Spring 的事务是通过数据库连接来创建的,同一个事务,只能用同一个数据库连接。而多线程场景下,拿到的数据库连接是不一样的,即会导致获取到的不同事务。既然是两个事务,则没办法进行统一回滚。