Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I put @Transactional annotation: at an interface definition or at an implementing class?

The question from the title in code:

@Transactional (readonly = true) public interface FooService {    void doSmth (); }   public class FooServiceImpl implements FooService {    ... } 

vs

public interface FooService {    void doSmth (); }  @Transactional (readonly = true) public class FooServiceImpl implements FooService {    ... } 
like image 823
Roman Avatar asked Jun 25 '10 17:06

Roman


People also ask

Can I use @transactional at interface?

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.

Where should I put @transactional?

Putting @Transactional requires Spring libraries in the API section, which IMHO is not effective. So I prefer to add it in the Implementation where the transaction is running.

Where does the @transactional annotation belong?

The @Transactional annotation belongs to the Service layer because it is the Service layer's responsibility to define the transaction boundaries.

Can we use @transactional on class?

@Transactional on a class applies to each method on the service. It is a shortcut. Typically, you can set @Transactional(readOnly = true) on a service class, if you know that all methods will access the repository layer. You can then override the behavior with @Transactional on methods performing changes in your model.


1 Answers

From http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

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.

Note: Since this mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

(Emphasis added to the first sentence, other emphasis from the original.)

like image 172
Romain Hippeau Avatar answered Sep 23 '22 02:09

Romain Hippeau