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 ?
The answer your question is no - @Transactional will have no effect if used to annotate private methods. The proxy generator will ignore them. When using proxies, you should apply the @Transactional annotation only to methods with public visibility.
I USE THE @Transactional in @Controller and Just make a Generic Save Method and save all the entities/ model using this simple save method. and if any method fail to save then all the transactions in controller rollback successfully.
You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies.
Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.
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
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With