조회 전용 트랜잭션에
readOnly = true
속성을 사용하면 성능을 높일 수 있으며, 불필요한/의도하지 않은 데이터의 변경을 예방할 수 있다.
지금까지는 이 정도로만 알고 사용해왔지만, 내부적으로 어떻게 동작하는지는 몰랐다.
영속성 컨텍스트는 더티 체크(dirty check)라는 기능을 제공하며, 이를 위해서 영속성 컨텍스트 내부에 스냅샷을 보관한다.
하지만
readOnly
를 사용할 경우 스냅샷을 보관하지 않는다.
스냅샷은 추가적인 메모리를 사용하기 때문에, 스냅샷을 보관하지 않는다면 메모리 사용량을 줄일 수 있는 것이다.
❗️ 물론 1차캐시는 그대로 사용한다.
Spring은 readOnly
속성이 추가된 트랜잭션의 Session Flush Mode
를 MANUAL로 설정하기 때문에, 명시적으로 flush()
해주지 않는 이상 트랜잭션 종료 시 flush가 일어나지 않는다.
이 뿐만 아니라, 명시적으로
readOnly = true
이 명시되어 있다면 조회 작업이라는 것을 직관적으로 알 수 있기 때문에 가독성 측면에서도 도움이 된다고 생각한다.
MySQL에서는 readOnly를 사용할 경우, SELECT
문에 대한 기능만을 지원하기 때문에, Transaction ID를 관리하지 않아도 되므로 성능이 향상된다.
만일 DB가 이중화 구성(master-slave 구조)
되어있다면, readOnly를 사용할 경우 읽기 전용으로 slave를 호출하기 때문에, 이 경우 성능을 향상시킬 수 있다.