之前项目里有段代码,一个接口对应两个实现类,然后两个实现类的公共逻辑又提取出来放到一个抽象类中,然后抽象类中的逻辑有一个方法加上了@Transactional注解,但是实际执行过程中事务没有生效,于是开始了漫漫的查找问题之路
先是怀疑数据库连接配置有问题,因为之前同事在另一个项目里遇到了同样的问题,最后发现是数据库连接每次都是会使用新的,没有使用当前的。然后那个项目数据库配置是在类里,这个项目是在xml里,没有发现配置有什么问题,放图 发现没有配置注解驱动
<!- -注入 事务管理器 这个注解驱动 告诉 spring 注解驱动 具体上网搜索 --> <tx:annotation-driven transaction-manager=“transactionManager”/>
配置完之后再试,发现还是有问题,继续查找
看过一些帖子之后发现 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,不建议使用!!!!!!!!
贴部分相关代码:
接口的实现方法
抽象类中的调用
这个方法会抛异常
抛异常的方法
还有些懵,不过下次应该会更快速找到问题,第一次写博客,记录一下!!!!!
异常一直往上抛,到最外层统一处理!+~~~~