spring AOP 的声明式事务 @Transactional失效的问题

spring AOP 的声明式事务 @Transactional失效的问题

问题

之前项目里有段代码,一个接口对应两个实现类,然后两个实现类的公共逻辑又提取出来放到一个抽象类中,然后抽象类中的逻辑有一个方法加上了@Transactional注解,但是实际执行过程中事务没有生效,于是开始了漫漫的查找问题之路

过程

怀疑数据库连接配置

先是怀疑数据库连接配置有问题,因为之前同事在另一个项目里遇到了同样的问题,最后发现是数据库连接每次都是会使用新的,没有使用当前的。然后那个项目数据库配置是在类里,这个项目是在xml里,没有发现配置有什么问题,放图
spring AOP 的声明式事务 @Transactional失效的问题_第1张图片
spring AOP 的声明式事务 @Transactional失效的问题_第2张图片
发现没有配置注解驱动


配置完之后再试,发现还是有问题,继续查找

在网上寻求答案

看过一些帖子之后发现
1.@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上 。
2.@Transactional 注解只能应用到 public 可见度的方法上 。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。

发现代码里的方法是类的protected方法,改为public,结果还有问题

继续搜寻原因,发现这篇帖子,
https://segmentfault.com/a/1190000014617571
对比自己的代码,原来是一样的问题:外层有方法把异常catch住了,需要手动回滚;
在catch逻辑里面,加入代码
// 手动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

然后就生效了,解决!!!

2018.11.06改
手动回滚代码会报500,所以最后还是在@Transactional注解那块的外面try catch了,最简单的方式,第一次写的博客我也不打算修改,贴上以便之后回顾,主要是@Transactional注解失效那块是值得注意的地方~~~~

总结

要spring声明式事务有效:
1.要配置事务管理器,并注入
2.事务注解要加在接口的实现方法上
3.如果逻辑里有catch异常,需要手动回滚事务
本次解决:
在接口的实现类上加入注解:@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
然后里面的方法调用要么直接抛异常,如果是catch的话需要在catch的逻辑里面加入手动回滚事务,TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

2018.11.06改
以上手动回滚会报500,不建议使用!!!!!!!!

贴部分相关代码:

接口的实现方法
spring AOP 的声明式事务 @Transactional失效的问题_第3张图片

抽象类中的调用
spring AOP 的声明式事务 @Transactional失效的问题_第4张图片

这个方法会抛异常
spring AOP 的声明式事务 @Transactional失效的问题_第5张图片

抛异常的方法
spring AOP 的声明式事务 @Transactional失效的问题_第6张图片

还有些懵,不过下次应该会更快速找到问题,第一次写博客,记录一下!!!!!

异常一直往上抛,到最外层统一处理!+~~~~

你可能感兴趣的:(java,spring,事务)