由于A类的a方法中涉及到切换数据源,由于事务的存在,数据源切换不生效。为了解决这个问题,将数据入库部分单独写成一个方法(insert),并用事务注解标注。
a方法去掉事务注解,并在a方法内完成数据源切换,切换后再调用insert方法,可以实现数据源的正常切换。
但是,insert方法的事务并不生效。
原因如下:
@Service
class A{
@Transactinal
method insert(){...}
method a(){
b();
}
}
// Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个startTransaction()方法:
class proxy$A{
A proxyA = new A();
method insert(){
startTransaction();
proxyA.b();
}
method a(){
proxyA.a();
}
}
我们如果按原来方法调用,执行完A方法后,调用还是a方法内的insert方法。a方法内的insert方法没有startTransaction()事务功能。所以事务不生效。
解决:
调用insert方法时,使用代理对象内的insert方法,即可开启事务。
共两步:
1、启动类增加注解:
@EnableAspectJAutoProxy(exposeProxy = true)
2、a方法调用insert前,从AOP的上下文中获取当前代理对象,使用代理对象调用insert方法
A proxyA = (A) AopContext.currentProxy();
proxyA .insert(..);
class A{
@Transactinal
method insert(){
...
}
method a(){
...
A proxyA = (A) AopContext.currentProxy();
proxyA.insert(..);
}
}