원래 @Transactional 어노테이션을 선언하게 되면 변경 감지(Dirty Checking)가 이루어지게 되지만 readOnly = true로 설정하면 스프링 프레임워크는 JPA의 세션 플러시 모드를 MANUAL로 설정한다.
그로 인해 해당 어노테이션 영역 내에서는 트랜잭션 내에서 강제로 flush()를 호출하지 않는 한 수정 내역이 DB에 적용되지 않으며, 조회용으로 가져온 Entity의 예상치 못한 수정을 방지할 수 있다.
또한, readOnly = true를 설정하면 JPA는 해당 트랜잭션 내에 조회하는 Entity가 조회용임을 인식하고, 변경 감지를 위한 Snapshot을 따로 보관하지 않으므로 메모리가 절약되는 성능상 이점 역시 존재한다.
그런데 애초에 조회 메서드에 @Transational 어노테이션을 달지 않으면 어떨까?
@Transactional 어노테이션을 선언하지 않는 것과는 어떤 차이가 있을까?
이 부분을 알기 위해서는 먼저 OSIV를 알아야 한다.
OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 유지하는 기능이다. 본래 영속성 컨텍스트는 트랜잭션 생명 주기와 동일하지만 이 옵션이 true로 설정되어 있다면 영속성 컨텍스트의 생명주기를 View까지 유지시켜 Entitiy의 Lazy Loading이 가능하도록 한다. ( OSIV 옵션은 기본이 true이다. )

사실 OSIV 옵션이 true로 설정되어 있으면 @Transactional 어노테이션 유무의 차이를 알 수가 없다.
그러나 OSIV 옵션이 false로 설정된다면 영속성 컨텍스트는 트랜잭션의 생명주기와 동일하기 때문에 Entitiy는 영속성 컨텍스트의 관리를 받지 않는 준영속 상태가 되어버린다.
영속성 컨텍스트가 준영속 상태가 된다는 말은 곧, Lazy Loading의 동작이 불가능하다는 의미이다.

해당 상태에서 Lazy Loading을 사용하게 되면 LazyInitializationException이 발생하기 때문에 조회용 메서드라고 하더라도 @Transactional 어노테이션을 붙여주어야 한다.
spring.jpa.open-in-view: truespring.jpa.open-in-view: false@Transactional(readOnly=true) 어노테이션을 선언하면 Entity의 수정 방지와 변경 감지를 위한 Snapshot을 따로 저장하지 않아 메모리적인 이점이 있다.
만약 OSIV 옵션이 true라면 해당 어노테이션을 사용하지 않아도 상관이 없지만 만약 옵션이 false라면 Exception이 발생할 수 있기 때문에 사용해야 한다.