记一次spring事务注解不生效经历

先说结论service 内部方法间相互调用事务不会生效,也就是说 service 内一个不带 @Transactional 的方法调用一个带有 @Transactional 的方法,此时事务不会生效。

一次在工作中需要将交换数据写入对方的交换库,于是我想到用 spring 的 JdbcTemplate 来实现,代码写好后,由于我是以一个工单为纬度写入数据,一个工单相关数据应该在同一个事务中提交,我就想着测试一下事务回滚效果,结果并没有回滚。一开始我的数据源等配置有问题,开始上网查找 JdbcTemplate 的事务配置,一看没毛病啊,由于我一开始就认为是事务相关的配置没设置好,于是一直换各种实现方式。

直到我重新写了一个测试方法,在其他类中直接调用测试方法,居然回滚成功了,但是换回原来的方法就是不生效,所以可以知道问题出在了调用方式上,原来我是在 service 中写了一个方法处理数据然后调用带有事务的方法,之前我只知道非 public 方法调用带事务的方法事务不会生效,没想到 service 内部方法间相互调用事务也不生效。

解决方案:1、是把调用方放到其他类中;2、在java配置类上添加注解 @EnableAspectJAutoProxy(exposeProxy = true) 方式代理对象,然后在 service 中通过代理对象 AopContext.currentProxy() 去调用方法。

@service
public class MyService {

    public void myMethodA(){
        ((service)ApoContext.currentProxy()).myMethodB(model);
    }

    @Transactional
    public void myMethodB(){
        // do something
    }
}

我用的方法1,所以没有测试方法2,但是思路是这样。

@Transactional 注解是通过AOP对方法增强,而AOP是通过代理或cglib生成增强类来实现的,在类中自调用的时候没有使用到代理所以事务不生效。

再说说我在排查问题时看到的可能导致事务不生效的情况,数据源不是托管给 spring 而是其他方法或者直接 new 出来的,而且多个 sql 对应的数据还不是同一个。可以通过断点事务管理器看看执行 doBegin 和 doCommit 时的情况,如果根本就没执行这两个方法,那就是事务完全没有生效,也就我这种情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值