spring-boothibernatespring-data-jpaspring-transactions

Should I apply @Transactional(readOnly = true) to a simple query method?


The advantages of transactions are known as ACID: Atomicity, Consistency, Isolation, and Durability. In methods like save and update, transactions are effective because they support dirty checking and various other features.

Also, when setting readonly to true, JPA recognizes that entities within that transaction are intended for read-only purposes, and it does not maintain separate snapshots for change detection, thus saving memory and providing performance benefits.

@Transactional(readOnly = true)
public Optional<Adate> getAdateByCalendarId(String calendarId) {
    return adateRepository.findAdateByCalendarId(calendarId);
}

However, I've come to think that for reads (R) in CRUD operations, excluding CUD (Create, Update, Delete), it might not be necessary to use @Transactional(readonly=true).

Here's a brief explanation for the reasons:

  1. Adding @Transactional(readonly=true) to simple queries can be considered over-engineering.
  2. I understand that entities retrieved during queries are stored in the first-level cache, but there's no need to store them in the first-level cache.

Have a nice day🙂 - kevin


Solution

  • When we work with one JPA repository we don't need Transactional annotation at all. It is applied by default:

    By default, methods inherited from CrudRepository 
    inherit the transactional configuration from 
    SimpleJpaRepository. 
    For read operations, the transaction configuration 
    readOnly flag is set to true. 
    All others are configured with a plain @Transactional 
    

    https://docs.spring.io/spring-data/jpa/reference/jpa/transactions.html

    Transactional annotation is important when we work with several repositories inside a single method and we have to do it in one transaction.

    It is important even for read operations, otherwise we can get not consistent data from several repositories.