聊一聊为什么同一个类中@Transactional和@Async调用失效问题

可能会遇到 为什么我加个@Transactional但是事务却没有生效,明明加了@Async但是却没有异步执行,其实这就是spring“捣的鬼”,spring动态代理原来的类已经不是原来的了,一个简单的例子搞明白真正原理!

@Service
class A{
@Transactinal
method b(){…}

method a(){    //标记1
    b();
}

}

//Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个startTransaction()方法:
class proxy$A{
A objectA = new A();
method b(){ //标记2
startTransaction();
objectA.b();
}

method a(){    //标记3
    objectA.a();    //由于a()没有注解,所以不会启动transaction,而是直接调用A的实例的a()方法
}

}

当我们调用A的bean的a()方法的时候,也是被proxyA拦截,执行proxyA拦截,执行proxyA.a()(标记3),然而,由以上代码可知,这时候它调用的是objectA.a(),也就是由原来的bean来调用a()方法了,所以代码跑到了“标记1”。由此可见,“标记2”并没有被执行到,所以startTransaction()方法也没有运行。

虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP的本质决定的。如果你在 protected、private或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

解决方案

1.把这两个方法分开到不同的类中;
2.把注解加到类名上面;

你可能感兴趣的:(spring,spring,boot,aop,java)