聊聊@transactional注解失效问题

1. @Transactional 控制事务

@Transactional是一种基于注解管理事务的方式,spring通过动态代理的方式为目标方法实现事务管理的增强。

用过Spring声明式事务的童鞋应该都知道@transactional这个注解,我们在接口, 类, 或者方法上使用@transactional注解, 就可以开启Spring的事务.

但有时也会发现明明加了@transactional注解, 却发现并没有控制住事务, 事务失效了...

2. @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(以非事务的方式执行,如果当前有事务则把当前事务挂起)

 3. 同一个类中方法(A调用B)事务失效问题总结:

1、如果只有A加@Transactional注解;则AB在同一事务中;
2、如果只有B加@Transactional注解;AB方法为同一类,事务失效;AB不同类,只有B有事务;

 

posted @ 2021-07-16 22:32  Sherlock先生  阅读(412)  评论(0编辑  收藏  举报