Spring中同一类中非事务方法调用事务方法不生效原因

一、原因解析

在项目加载的时候,spring会去扫描所有带有@transaction注解 的方法或者类,然后为他们生成一个代理类,然后代理类里面会持有原始类的引用,示例如下:

代理类:

AProxy{

    //A的真实对象引用

  private Object a;  

   public AProxy(Object a) {
        this.a= a;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在转调具体目标对象之前,可以执行一些功能处理
        System.out.println("doSomething before");
        // 转调具体目标对象的方法,也就是都Something这个方法
        Object o = method.invoke(a, args);
        // 在转调具体目标对象之后,可以执行一些功能处理
        System.out.println("doSomething after");
        return o;
    }

}

原始类:

A{ 

   public void doSomething() {
        System.out.println("call doSomething()");
        doEverything();
    }

    @transaction
    public void doEverything() {
        System.out.println("call doEverything(......)");
    }

}

也就是说,加了@transaction注解就会有事务属性是因为在代理类里面,spring在调用目标方法之前和之后做了事务的封装,我们在调用doSomething方法时是代理类在调用,而doSomething方法里面调用doEverything方法,实质执行的代码是this.doEverything(),此处this对象是实际的A对象而不是本该生成的代理对象,因此直接调用了doEverything()方法。所以不管doEverything()有没有打上事务注解,都不会生效

二、解决办法:

1、放到不同的类中进行调用

2、将之前使用普通调用的方法,换成使用代理调用
((A)AopContext.currentProxy()).doEverything();
获取到A的代理类,再调用事务方法,强行经过代理类,激活事务切面。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值