I am beginner and as I understand @Transactional
simply make sure that all the internal work of a class or method annotated with @Transactional
will be wrapped in one transaction and all of the calls from external sources will create a new transaction but why do we actually need these annotations in Repository below and what are advantages of using it with readOnly = true
in common cases? This is Spring pet-clinic example application using Spring & Hibernate (https://github.com/spring-projects/spring-petclinic).
/**
* Repository class for <code>Pet</code> domain objects All method names are compliant with Spring Data naming
* conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
* @author Sam Brannen
* @author Michael Isvy
*/
public interface PetRepository extends Repository<Pet, Integer> {
/**
* Retrieve all {@link PetType}s from the data store.
* @return a Collection of {@link PetType}s.
*/
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
@Transactional(readOnly = true)
List<PetType> findPetTypes();
/**
* Retrieve a {@link Pet} from the data store by id.
* @param id the id to search for
* @return the {@link Pet} if found
*/
@Transactional(readOnly = true)
Pet findById(Integer id);
/**
* Save a {@link Pet} to the data store, either inserting or updating it.
* @param pet the {@link Pet} to save
*/
void save(Pet pet);
}
If we use @Transactional(readOnly = true) to a method which is performing create or update operation then we will not have newly created or updated record into the database but we will have the response data.
The @Transactional annotation offers the readOnly attribute, which is false by default. The readOnly attribute can further be used by Spring to optimize the underlying data access layer operations.
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.
A read-only transaction or query is a transaction which does not modify any data.
From the explanation of Oliver Gierke - the Spring Data author:
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.
Further reading:
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