场景:
@Translation
void a(){
b();
c();
}
@Translation
void b(){}
@Translation
void c(propagation = Propagation.REQUIRES_NEW){}
在同一个类下,a,b,c三个方法都是事务,其中a方法调用b和c方法,且c方法事务传播方式为new
因为是用一个类中,直接这样调用必然会失效。即便c方法的事务传播方式为new,也无法生效,只能跟着a方法走。因为spring中事务是通过代理对象来控制的,在一个类中直接调用相当于复制粘贴,并没有使用代理对象。
如果b方法、c方法 和a方法不在同一个类中的话,那么在a类中通过@autowired注入b类和c类,则事务生效。因为@autowired实际上是通过JDK动态代理使用反射的方式来注入对象的,实现它的InvocationHandler接口,然后在handler方法中,通过反射来访问目标对象的@Autowired字段,并将相应的值注入到目标对象中,这里已经使用了代理。
如果在同一个类中,我们不可能去@autowired它自身,这样的话循环调用自己是会出大问题的。
解决方法:究其根本是因为在本类中直接调用其他方法相当于复制粘贴,绕过了代理对象。所以我们只需要使用代理就可以通过代理对象去控制。
前面说了IOC,spring还有一个特性是aop(面向切面编程),aop中有一个aspectj代理,具体使用方法:在pom.xml中添加aop-starter依赖,启动类上开启aspectj注解并对外暴露。就可以使用aopcontent去获取上下文对象,并放心的强转成本类,这样在用本类去调用b方法和c方法就是使用代理对象去控制,实现同一类中本地事务的处理。