Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use @Transactional with Spring Data?

I just started working on a Spring-data, Hibernate, MySQL, JPA project. I switched to spring-data so that I wouldn't have to worry about creating queries by hand.

I noticed that the use of @Transactional isn't required when you're using spring-data since I also tried my queries without the annotation.

Is there a specific reason why I should/shouldn't be using the @Transactional annotation?

Works:

@Transactional public List listStudentsBySchool(long id) {     return repository.findByClasses_School_Id(id); } 

Also works:

public List listStudentsBySchool(long id) {     return repository.findByClasses_School_Id(id); } 

Thanks in advance!

like image 713
Byron Voorbach Avatar asked May 01 '12 07:05

Byron Voorbach


People also ask

How is @transactional implemented in Spring?

Transactions and Proxies. At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

Why @transactional annotation is used in Spring?

The annotation @EnableTransactionManagement tells Spring that classes with the @Transactional annotation should be wrapped with the Transactional Aspect. With this the @Transactional is now ready to be used.

What is @transactional annotation in Spring boot?

The @Transactional annotation is metadata that specifies that an interface, class, or method must have transactional semantics; for example, "start a brand new read-only transaction when this method is invoked, suspending any existing transaction".

Can we use @transactional on 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.


1 Answers

What is your question actually about? The usage of the @Repository annotation or @Transactional.

@Repository is not needed at all as the interface you declare will be backed by a proxy the Spring Data infrastructure creates and activates exception translation for anyway. So using this annotation on a Spring Data repository interface does not have any effect at all.

@Transactional - for the JPA module we have this annotation on the implementation class backing the proxy (SimpleJpaRepository). This is for two reasons: first, persisting and deleting objects requires a transaction in JPA. Thus we need to make sure a transaction is running, which we do by having the method annotated with @Transactional.

Reading methods like findAll() and findOne(…) are using @Transactional(readOnly = true) which is not strictly necessary but triggers a few optimizations in the transaction infrastructure (setting the FlushMode to MANUAL to let persistence providers potentially skip dirty checks when closing the EntityManager). Beyond that the flag is set on the JDBC Connection as well which causes further optimizations on that level.

Depending on what database you use it can omit table locks or even reject write operations you might trigger accidentally. Thus we recommend using @Transactional(readOnly = true) for query methods as well which you can easily achieve adding that annotation to you repository interface. Make sure you add a plain @Transactional to the manipulating methods you might have declared or re-decorated in that interface.

like image 137
Oliver Drotbohm Avatar answered Sep 30 '22 18:09

Oliver Drotbohm