为什么我们不能使用@Transactional
静态方法来管理我的Spring项目中的事务?
@Transactional
适用于非静态方法但不适用于静态方法的任何特定原因?
答案 0 :(得分:10)
为了理解为什么你提出的建议不起作用,你必须首先从高层次上理解Spring如何处理使用@Transactional
的bean。
当您将方法或类注释为@Transactional
并使其成为Spring Bean时,Spring会有效地为该类创建代理(使用JDK动态代理或CGLIB代理)。这意味着无论何时使用您的类(来自Spring托管代码),都不会立即调用您的代码,而是首先执行所需操作的代理,然后调用您的代码(在缓存支持的情况下)甚至可能根本不会调用代码。
这里需要记住的一件重要事情是,调用代码(如果你愿意,调用站点)根本不会改变,并且JVM使用相同的字节码执行对所需目标方法(代理方法)的调用(< em> invokevirtual 或 invokeinterface )。
考虑到这一点,不支持静态的原因变得清晰。 您无法为静态方法创建代理!当然Java Dynamic Proxies不能这样做,CGLIB也不能。
支持这样的功能需要更改调用代码的字节码,因为调用静态方法是通过字节码中的invokestatic实现的,它对目标方法进行了硬编码。
This部分Spring文档详细解释了Spring AOP
答案 1 :(得分:1)
如果你正在使用AspectJ,这里有一个简单的,虽然很丑陋的解决方法:
public static void doWhatever(final String param) {
new Runnable() {
@Transactional
public void run() {
// do whatever in transaction...
}
}.run();
}
答案 2 :(得分:0)