Spring 事务的原理其实就是 AOP,进行切面增强,用到了代理对象,失效的根本原因是 AOP 不起作用了!常见情况如下:
(1)发生自调用,类里面使用 this 调用本类的方法(this 通常省略),而 this 对象不是代理类,而是(UserService)类本身的对象,没有用到代理类。
解决方法很简单,让 this 变成(UserService)类的代理类即可。
(2)方法不是 public 的
@Transactional 只能用在 public 的方法上,否则事务不会生效;如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
(3)数据库不支持事务
Spring 本身是基于数据库的事务,所以如果数据库不支持事务,Spring 也不支持,如 MySQL 中的 MyISAM 类型
(4)没有被 Spring 管理
比如没有在类上加 @Component、@Autowire 等注解,没有把对象放在容器中,只加 @Transactional 没作用。
(5)异常被吃掉,事务不会回滚(或者抛出的异常没有被定义,默认为 RuntimeException)