본문 바로가기
개발/Spring

@Transactional에 대한 정리[2] - (readOnly=true)에 관하여

by 설이주인 2023. 9. 11.

@Transactional에 대한 정리 [1]에서 작성했듯이  Service단을 전체적으로 @Transactional(readOnly=true)를 적용하고  rollback을 희망하는 부분에 대해서 메소드 별로 따로 @Transactional을 적용하고 있다고 밝힌적이 있습니다.

 

@Transactional(readOnly=true)가 기본적으로 성능 이점을 가져온다는 것은 알고 있지만 정확히 어떤 이점이 있는지에 대해서 자세히 정리 해본적이 없기에 정리해봅니다.

 

해당 이점은 JPA를 사용하면서 영속성 컨텍스트(Persistence Context)가 수행하는 변경 감지(Dirty Checking)과 연관 되어있습니다.

JPA는 사용하면 작업을 쭈우우우욱 진행하고 쓰기 지연 저장소에 있는 SQL query를  flush한 이후 Commit을 진행해서 update 없이 Entity 수정을 이뤄낼 수 있으며 이를 Dirty Checking, 변경 감지라고 한다.

 

이때 readOnly = true를 설정하면 스프링 프레임워크는 JPA 세션 플래시 모드를  MANUAL로 설정한다. 요기서 MANUAL 모드는 트랜잭션 내에서 사용자가 수동으로  flush를 호출하지 않는 이상 flush의 자동 수행을 진행하지 않는 모드이다.

즉, 해당 트랜잭션 안에서  flush를 강제로 실행하지 않는 이상 수정 내역이  DB에 저용되지 않는다.

 

이렇기에 commit시 영속성 컨텍스트가 자동으로 flush가 되지 않기에  entity와 개발자가 예상하지 못하는 수정을 방지할 수 있다. 그리고  readOnly = true를 설정하면 JPA가 해당 트랜잭션 내에서 조회하는  Entity는 조회용으로 인식하기에 SnapShot을 따로 보관하지 않아서 메모리가 절약되는 성능 이점을 볼 수 있다.

 

추가적으로 좋은 부분..

  • 가독성이 좋아진다.
  • Replication 부하 분산 > 실운영 서비스에서는 데이터베이스의 장애를 빠르게 복구, 트래픽 분산을 위해서  repliacation 방식을 사용한다. 만약에  replication 상태에서  readmOnly = true가 설정 되어있는 메서드라면  Slave DB에서 데이터를 가져오도록 동작하며 이를 통해서 replication의 목적에 맞게 트래픽 분산을 온전하게 적용 할 수 있다.

 

 

JPA를 사용할때 예상하지 못한 수정이 이뤄지는 상황을 최대한 방지해야하기에 가능하면 비즈니스 로직에 readOnly = true를 꼭 붙여주자.. 무려 가독성과 성능 이점까지 있는데 안 할 이유가 없다고 생각한다.