@Transactional(read only = true)를 사용해야 하는 이유

조현근·2022년 11월 27일
1
post-thumbnail

개발을 하면 반드시 사용하게 되는 @Transactional, 여기엔 read only라는 옵션이 있습니다.
read only를 true로 설정하면 어떤 이점이 있는지 알아보겠습니다!!

이번 포스트는 MySQL에 대해서만 read only = true일때 장점을 알아보겠습니다!!

1. CRUD 연산 중 CUD만 발생한다.

DB에 따라 @Transactional(readOnly = true)를 했을 때 update나 insert 연산이 수행된다 하여도 오류가 날 수도 있고 나지 않을 수도 있다 합니다. 학습테스트를 통해 주로 사용하는 DB인 MySQL에서 어떻게 동작하는지 알아보겠습니다.

2. flush가 일어나지 않는다.

flush가 일어나지 않아 특성에 대해 알아보겠습니다.

2-1. flush가 일어나지 않아 JPA를 사용하는 경우 dirty checking이 발생하지 않는다.

우선 dirty checking이 무엇이고 어떻게 동작하는지 알아보겠습니다.

Dirty checking(변경감지)란?

변경감지는 JPA가 entity를 관리하는 방법 중 하나입니다.
JPA는 entity를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해둡니다(스냅샷을 떠놓음). 그리고 flush 시점에 스냅샷과 entity를 비교해 변경된 엔티티를 찾습니다.
변경감지는 아래와 같은 순서로 진행됩니다.
1. 트랜잭션을 commit하면 entity manager 내부에서 먼저 flush가 호출된다.
2. entity와 스냅샷을 비교해 변경된 entity를 찾는다.
3. 변경된 entity가 있으면 수정 쿼리를 생성해 쓰기 지연 SQL 저장소에 보낸다.
4. 쓰기 지연 저장소의 SQL을 DB에 보낸다.
5. DB의 transaction을 commit한다.

변경감지가 이루어지려면 flush가 일어나야되는데, readOnly=true인 경우 flush가 일어나지 않아 변경감지 또한 일어나지 않습니다. 변경감지가 일어나지 않아 스냅샷을 저장하지 않고 스냅샷 인스턴스를 보관하는 메모리를 아낄 수 있습니다. 또한 스냅샷과 entity를 비교하는 연산이 일어나지 않아 성능 향상 또한 일어납니다.

3. Master-Slave 구조를 사용하는 경우 DB 트래픽을 분산할 수 있다.

추가적인 설정을 통해 readOnly=true와 readOnly=false의 쿼리를 slave, master DB로 트래픽을 분산할 수 있다고 합니다.

어떻게 분기하는지는 다른 분의 포스트를 가져왔습니다! 추후 시간이 되면 한 번 시도해보고 포스팅하도록 하겠습니다!
Master - Slave 구조에 따른 Read, Write 분기

4. InnoDB 엔진을 사용하는 경우 transaction ID를 세팅하는 오버헤드를 줄일 수 있다.

MySQL 8.0 공식문서에 의하면

InnoDB는 readOnly가 true로 설정되어 있으면 transaction Id를 얻어오기 위한 오버헤드를 피할 수 있다.

라고 설명합니다.

아래는 공식문서 링크입니다!
공식문서

출처

https://www.inflearn.com/questions/17261
자바 ORM 표준 JPA 프로그래밍
https://dev.mysql.com/doc/refman/8.0/en/innodb-performance-ro-txn.html
https://k3068.tistory.com/102

profile
안녕하세요!

0개의 댓글