You should use @Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in ...
The controller can be made @Transactional , but indeed it's a common recommendation to only make the service layer transactional (the persistence layer should not be transactional either).
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
So when you annotate a method with @Transactional , Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.
I have seen many comments in stack-overflow articles I found certain things about either @Transactional use with @Service or with @Controller
"Usually, one should put a transaction at the service layer."
"The normal case would be to annotate on a service layer level"
"Think transactions belong on the Service layer. It's the one that knows about units of work and use cases. It's the right answer if you have several DAOs injected into a Service that need to work together in a single transaction." [Source]
Drawback to use @transactional with @service layer
If I had 2 methods for example saveUser() and saveEmail() (because I store the emails in a database to send them later - like a queue) I would create in my service a method saveUserAndSendEmail(User user) which would be transactional. [Source]
It means I create many methods in service layer instead of one Save Generic Method as follow
public <T> long save(T entity) throws DataAccessException { Session session = sessionFactory.getCurrentSession(); long getGenVal=(Long) session.save(entity); return getGenVal; }
According to the above solution , it means we have many methods like following LOL..
public <T> long saveAccount(T entity)....
public <T> long saveWithAuditLog(T entity, K entity1)....
public <T> long saveWithAuditLogAndEntries(T entity, K entity, M entity)....
OVERCOME this situation
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.
Other situation that ensure that @Transactional should be use with @Controller
In @Controller:
pt.save(entity1); pt.save(entity2); int a = 2/0; pt.save(entity3);
In case , @Transactional on Service, first 2 entity successfully saved but third not it not rollback all the transaction
In case , @Transactional on @Controller all the transaction rollback as exception occur
why stack-overflow asked , "Don't do transactions in your controller. Put them in your service layer classes."? [source]
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