从Spring源码解析事务失效问题-调用同一个类方法失效

在讨论Spring中事务失效问题前请参考Spring代理文章

Spring设计模式-代理模式

1,首先明确一点

在开启事务后,从Spring中获取的对象是代理对象ProxyFactory并不是UserService对象

public class ProxyFactory{


    private UserService target;
    public ProxyFactory(Object target){
        this.target=target;
    }

   //给目标对象生成代理对象
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
				(proxy, method, args) -> {
					System.out.println("代理方法执行前.....");
					//执行目标对象方法
					Object returnValue = method.invoke(target, args);
					System.out.println("代理方法执行后.....");
					return returnValue;
				}
		);
    }

}
————————————————
版权声明:本文为CSDN博主「老马回头不吃草」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014533485/article/details/107529445

2,假设我们现在执行方法

@Trancational
public void a(){
    
    // sql插入
    xxxxxx
    b();
}

@Trancational
public void b(){

    // sql插入
    xxxxx
    //抛出异常
    throw .....
}

此时B方法的事务是不会生效的!!

因为此时调用b()的方法是target对象 而不是代理对象

只有代理对象才会执行事务代码,走事务

然而此时执行的代码如下:

public class ProxyFactory{


    private UserService target;
    public ProxyFactory(Object target){
        this.target=target;
    }

   //给目标对象生成代理对象
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
				(proxy, method, args) -> {
					System.out.println("代理方法执行前.....");
                                              
                                        // 开启事务
                                        transactionManager.
                                            getTransaction(transactionDefinition);
					//执行目标对象方法
					Object returnValue = method.invoke(target, args);
                                        //** 此时的method = A(){B()}
                                        //** 统一走在了同一个事务里面

                                        //   提交事务
                                        transactionManager.commit(status);
					System.out.println("代理方法执行后.....");
					return returnValue;
				}
		);
    }

}

如何解决?

1,从Spring容器中获取代理对象

2,将方法拆分到不用的对象中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值