@Transactional是一种基于注解管理事务的方式,spring通过动态代理的方式为目标方法实现事务管理的增强。
用过Spring声明式事务的童鞋应该都知道@transactional这个注解,我们在接口, 类, 或者方法上使用@transactional注解, 就可以开启Spring的事务....
但有时也会发现明明加了@transactional注解,,却发现并没有控制住事务,,事务失效了...
总结下来,,大概有以下几种场景会使得@transactional注解失效
1.数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的
2.方法必须是public的, 否则spring无法生产动态代理
3.方法抛出的异常类型是不是unchecked异常. 默认情况下,Spring会对unchecked异常进行事务回滚(如空指针异常、算术异常等,会被回滚),如果是checked异常则不回滚(文件读写、网络出问题,spring就没法回滚了)。
通过@Transactional(rollbackFor=Exception.class)可以让checked异常也回滚
4.是不是同一个类中存在方法调用(如A()方法调用同一个类中的B()方法, A()方法没有@transactional, B()方法有@transactional).
因为spring的注解事务控制是基于代理对象的,如果是方法内部调用话压根没走代理对象.
解决:通过 ((Service)AopContext.currentProxy()).B() 来调用B方法,其中Service是A,B方法所在类名
5.是否开启了对注解的解析
<tx:annotation-driven transaction-manager=“transactionManager” proxy-target-class=“true”/>
6.异常是不是被你catch住了,并没有抛出
7.spring事务传播属性设置错误
比如:PROPAGATION_NOT_SUPPORIED(以非事务的方式执行,如果当前有事务则把当前事务挂起)