4
votes

Spring doc has the two recommendations:

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.

(from http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html)

and

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice).

(from http://static.springsource.org/spring/docs/3.0.x/reference/aop.html#aop-understanding-aop-proxies)

Do I understand correctly that in order to follow both recommendations, I need to have @Transactional annotation on concrete class, but still provide an interfaces (that this class implements) containing all transactional methods, so that Spring can use JDK dynamix proxies for this interface?

1
Yes, your understanding is correct.gkamal
BTW: I recommend to use Compile Time AspectJ, then the Aspects get taken in accout even if you invoke a method from inside the same bean (this.otherMethod()).Ralph

1 Answers

2
votes

It works like this

  1. Have a business interface with methods, do not annotate interface methods with @Transactional

  2. Write an implementation class for interface defined above and annotate methods in impl class with @Transactional

As spring recommends usage of JDK dynamic proxies which are interface based hence we need to have business interface in place. Also, as stated

Java annotations are not inherited from interfaces

We need to annotate concrete / implementation class methods with @Transactional