Question

Why cant we use @Transactional for static methods to manage the transactions in my spring Project ?

@Transactional works well for non static method but not for static methods any specific reason ?

Was it helpful?

Solution

In order to understand why something like what you are proposing does not work you have to first understand at a high level how Spring handles beans that use @Transactional.

When you annotate a method or the class as @Transactional and make it a Spring Bean, Spring effectively creates a proxy for that class (using JDK Dynamic proxies or CGLIB proxies). That means that whenever your class is used (from Spring managed code that is), it's not your code that gets called immediately, but the proxy which first does whatever is needed, and then your code is called (in the case of caching support your code would perhaps not even be called at all). A key thing to remember here is that the invoking code (the call site if you will) does not change at all, and the invocation of to the required target method (the proxy method) is performed by the JVM using the same bytecode (invokevirtual or invokeinterface).

With that in mind, the reason that static is not supported becomes clear. You can't create a proxy for static method! Of course Java Dynamic Proxies cannot do this, and neither can CGLIB.

Supporting such a feature would require changing the bytecode of the invoking code, since calling a static method is implemented via invokestatic in bytecode, which hard-codes the target method.

This part of the Spring documentation explains Spring AOP in details

OTHER TIPS

If you're using AspectJ, here's a simple, albeit ugly, workaround:

public static void doWhatever(final String param) {
    new Runnable() {
        @Transactional
        public void run() {
            // do whatever in transaction...
        }
    }.run();
}

This is feasible using:

  1. @EnableTransactionManagement(mode = ASPECTJ) (or its XML equivalent)
  2. all the configuration required to make AspectJ work
  3. registering a custom aspect to handle @Transactional over static methods like this one I just stumbled upon (did not test it)

NB: in this post I asked about how to make package-private methods @Transactional.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top