常见的失效场景
1.数据库引擎的原因
如果使用 MySQL 且引擎是 MyISAM,则事务会不起作用,原因是 MyISAM 不支持事务,改成 InnoDB 引擎则支持事务。
2. 修饰的方法原因
注解 @Trasactional 只能加在 public 修饰的方法上事务才起效。如果加在 protect、private 等非 public 修饰的方法上,事务将失效。
3.异常没有抛出的原因
如果在开启了事务的方法内,使用了 try-catch 语句块对异常进行了捕获,而没有将异常抛到外层,事务将不起效。
4.方法调用的原因
在不同类之间的方法调用中,如果 A 方法开启了事务,B 方法没有开启事务,B 方法调用了 A 方法。如果 B 方法中发生异常,但不是调用的 A 方法产生的,则异常不会使 A 方法的事务回滚,此时事务无效。如果 B 方法中发生异常,异常是调用的 A 方法产生的,则 A 方法的事务回滚,此时事务有效。在 B 方法上加上注解 @Trasactional,这样 A 和 B 方法就在同一个事务里了,不管异常产生在哪里,事务都是有效的。
简单地说,不同类之间方法调用时,异常发生在无事务的方法中,但不是被调用的方法产生的,被调用的方法的事务无效。只有异常发生在开启事务的方法内,事务才有效。
在同一个类的方法之间调用中,如果 A 方法调用了 B 方法,不管 A 方法有没有开启事务, B 方法的事务是无效的。
5重复扫描
如果使用了Spring + MVC,则 context:component-scan 重复扫描问题可能会引起事务失效。