mjeongriver
Published 2023. 11. 22. 11:27
@Transaction(readOnly=true) TIL/JPA

* 트랜잭션이란?

- 데이터베이스의 상태를 변경하고자 할 때, 한번에 수행되어야 하는 연산을 의미하고 예외 발생시 rollback 처리를 자동으로 수행함

- 쿼리문중 insert, select, update, delete 등의 동작들의 작업 단위를 트랜잭션이라고 함

- 어떤 한 서비스 로직 안에 서로 다른 엔티티의 값을 변경한다고 예를 들면 A 엔티티 속성이 바뀌고 B 엔티티 속성이 바뀌기 전에 에러가 나게 되면 A 엔티티 속성을 다시 전으로 돌려줘야 함(ACID에 근거) → 그래서 데이터가 바뀌는 곳에는 @Transactional 어노테이션을 붙여 트랜잭션을 처리한다

 

* @Transaction의 readOnly 속성

- 트랜잭션을 읽기 전용으로 설정하는 속성
- default 값이 false

 

* 조회한 값을 return 해주는 메소드에 당연하게 @Transaction(readOnly=true)를 사용했는데 왜 쓰는걸까에 대한 의문이 생겼다

- 검색을 통해 찾아보니 써주는게 좋다고 한다.

1) 조회 데이터를 return 한다고 해도 의도치 않게 데이터가 변경되는 일을 사전 방지

2) cud 작업이 동작하지 않고, 변경 감지의 작업을 수행하지 않아 성능 향상

3) 상황에 따라 DB 서버의 부하를 줄이고 약간의 최적화 가능

4) 코드를 접하는 사람들이 직관적으로 보기에 해당 메서드는 read에 대한 동작만 수행한다고 예상할 수 있음

5) 트랜잭션에 readOnly=true 옵션을 주면 스프핑 프레임워크가 하이버네이트 세션 플러시 모드를 MANUAL로 설정한다.

이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않는다. 따라서 트랜잭션을 커밋하더라도 영속성 컨텍스트가 플러시 되지 않아서 엔티티의 등록, 수정, 삭제가 동적하지 않고, 또한 읽기 전용으로, 영속성 컨텍스트는 변경 감지를 위한 스냅샷을 보관하지 않음으로 성능이 향상된다. 

 

1] 하이버네이트 세션 플러시란?

  • 하이버네이트는 ORM 도구로, 자바 객체를 데이터베이스 행과 매핑합니다. 세션 플러시는 하이버네이트 세션(데이터베이스와의 연결) 내의 임시 변경 사항(영속성 컨텍스트에 있는 변경 내용)을 데이터베이스에 반영하는 과정
  • 플러시가 일어나면, 변경된 엔티티들이 데이터베이스에 반영(등록, 수정, 삭제 등)

2] readOnly=true 옵션의 효과

  • 이 옵션은 해당 트랜잭션이 데이터를 변경하지 않고 오직 읽기만 수행할 것임을 나타냄
  • 스프링 프레임워크는 이 옵션이 설정되면 하이버네이트 세션의 플러시 모드를 MANUAL로 설정함. 이는 트랜잭션 동안 자동 플러시를 방지하여 데이터베이스에 대한 불필요한 쓰기 작업을 줄임

3] 성능 향상의 이유

  • readOnly 모드에서는 변경 감지(예: 엔티티의 상태 변화 감지)를 위한 스냅샷 보관이 필요 없음. 변경 감지는 보통 엔티티가 수정되었는지를 확인하기 위해 이전 상태의 스냅샷과 현재 상태를 비교하는 과정이다.
  • 읽기 전용 모드에서는 이러한 비교 과정이 필요 없으므로 성능이 향상됨. 메모리 사용량 감소와 계산 오버헤드 감소가 이에 해당

4] 실제 사용 시 주의사항

  • readOnly=true를 사용할 때는 해당 트랜잭션이 데이터를 수정하지 않아야 함. 데이터를 변경하는 로직이 포함되어 있다면, 이 옵션을 사용하면 변경 사항이 데이터베이스에 반영되지 않을 수 있음.
  • 데이터를 읽기만 하는 조회 쿼리, 리포팅 등에서 주로 사용됨.

'TIL > JPA' 카테고리의 다른 글

DTO와 Entity를 분리해서 사용하는 이유  (0) 2024.01.18
@Entity, @Table 차이점  (0) 2024.01.18
profile

mjeongriver

@mjeongriver

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그