Where to put @Transactional? In interface specification or implementation? [duplicate]

What is considered the best practice in placing the @Transactional annotation? Should I annotate the interface method or the implementation?


Solution 1:

It really all depends on your application architecture, in my opinion. It depends on how you are proxying your classes. If you have your app set to proxy-target-class='true' (in your application context, then your @Transactional information wont be picked up if you annotate the Interface.

Check out The Spring Docs -- "Tips" for more information.

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. 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. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

Solution 2:

Good question. I've always put it in the implementation. Perhaps because it is an implementation detail, rather than an abstraction.

You may want different implementations to have different transactional behaviours.

El Guapo noted that, in addition to that, there are more issues that can arise from putting on on the interface, related to the proxying strategy.

Solution 3:

While transactions management is implementation detail in many cases quite often it's an interface detail as well. For example, when defining interface of services of your application you might consider putting @Transactional into interface definition to specifically clarify what propagation strategy you're using.