I was reading this regarding to where to place Transactional(interface vs implementation):
The Spring team's recommendation is that you only annotate 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 will only work as you would expect it to if you are using interface-based proxies. The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy (which would be decidedly bad). So please do take the Spring team's advice and only annotate concrete classes (and the methods of concrete classes) with the @Transactional annotation.
So the question is what is interface-based proxy exactly and how can I see if it is used? Is it some configuration or it is the way how I instantiate/use instances?
If Spring cannot create a JDK proxy (or if you force Spring to create a CGLIB proxy by setting proxyTargetClass to true) then the code will not execute in a transactional context because (as the Spring docs state):
The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy
So, I think your concerns are:
How can you be sure that Spring does not create a CGLIB proxy
You must be configuring AOP based transactional support. If you are doing this by using <tx:annotation-driven/>
then the default value for proxy-target-class (false) will suffice though could be explicit about this by setting: <tx:annotation-driven proxy-target-class=“false"></tx:annotation-driven>
. If you are configuring transactional support in some other way (using Java config, for example) then just ensure that the value of TransactionProxyFactoryBean.proxyTargetClass
is false.
How can you be sure that your @Transactional annotations are respected
This is easy, just annotate the concrete class with the @Transactional
annotation instead of annotating the interfaces. This avoids any issues with proxying.
In summary, Spring should use interface based proxying as long as TransactionProxyFactoryBean.proxyTargetClass
is false however, if you annotate a concrete class rather than an implementation then the issue of proxying won't affect transactional support.