Q: @Transactional(readOnly=true) 를 사용하는 이유
A: 조회만 수행하는 작업일 경우 readOnly 옵션을 true로 하여 성능 및 가독성을 향상시킬 수 있다
→ 여기서 드는 의문🤔 : 그냥 @Transactional 을 안 쓰면 안 되나?
트랜잭션을 무분별하게 사용하는 것도 좋진 않다는데, 그럼에도 불구하고 ‘굳이’ 조회용 로직에 @Transactional(readOnly=true) 를 입히는 어떤 경우이고, 그 이유는 무엇일지 알아보자
✅ @Transactional(readOnly=true) 사용 시 장점
@Transactional(readOnly=true)는 단순히 읽기용임을 표시하는 것 이상의 역할을 한다.
영속성 컨텍스트 최적화 (성능 향상)
: JPA는 엔티티의 변경 여부를 확인하기 위해 '스냅샷'을 유지하는데, readOnly=true를 설정하면 이 스냅샷을 만들지 않고 변경 감지(Dirty Checking) 과정을 생략하므로 CPU와 메모리 리소스를 아낄 수 있다.
DB 부하 분산 (Replication)
: DB를 Master(Write)와 Slave(Read-only)로 분리해 운영할 때, 이 옵션을 기준으로 조회 쿼리를 Slave DB로 자동 분기할 수 있다.
데이터 일관성 유지
: 하나의 트랜잭션 내에서 여러 번의 SELECT를 할 때, 격리 수준에 따라 동일한 데이터 상태(Snapshot)를 보장받을 수 있다.
실수 방지
: 의도치 않게 데이터를 변경하는 코드가 포함되어도, DB 수준에서 에러를 내거나 반영을 막아 데이터 무결성을 지켜준다.
💡 @Transactional(readOnly=true)을 쓰는게 효과적인 경우
지연 로딩(Lazy Loading)
- 지연 로딩 : 객체를 실제 사용할 때 DB에서 가져오는 기능
- 트랜잭션이 살아있어야만 동작함 (메서드가 끝날 때까지 영속성 컨텍스트가 유지되어 안전하게 연관 데이터를 가져옴)
일관된 데이터 보기
- 예를 들어, 하나의 요청 안에서 여러 번의 조회가 발생할 때
- 첫 번째
SELECT와 두 번째SELECT사이에 다른 사용자가 데이터를 수정/삭제하면, 한 화면에 일관되지 않은 데이터가 보일 수 있다 → 트랜잭션을 사용하면 내가 조회를 시작한 시점의 스냅샷을 유지하여 일관된 데이터를 보장받을 수 있음
Replication
- DB Replication : 동일한 DB를 복제하여, Master/Slave 구조를 활용하여 DB 의 부하를 분산시키는기술
- 애플리케이션은 어떤 쿼리가 '조회'인지 '수정'인지 스스로 완벽히 판단하기 어려움 → 이때
@Transactional(readOnly=true)옵션이 있으면, 스프링은 이를 "이 작업은 읽기 전용이니까 Slave DB로 가도 돼!"라는 신호로 인식 - 이 옵션이 없으면 스프링은 안전을 위해 모든 요청을 Master DB로 보낼 가능성이 높음 → Slave DB를 아무리 많이 만들어놔도 Master 서버만 과부하가 걸려 Replication을 구축한 의미가 없어짐 + 단순 조회임에도 불구하고 소중한 Master DB의 자원을 낭비하게 됨
[참고]
https://hungseong.tistory.com/74
@Transactional(readOnly = true)를 왜 붙여야 하나요
스프링으로 개발하면서 필연적으로 사용하게 되는 @Transactional. 우리는 스프링의 AOP를 통해 @Transactional 어노테이션만으로 손쉽게 Service Layer에서 트랜잭션을 걸 수 있다. 일반적으로, 조회용 메서
hungseong.tistory.com
'백엔드 > Spring Boot' 카테고리의 다른 글
| [Spring Boot/JPA] 엔티티 매핑 초보자 가이드: 복합 키, 상속, 그리고 DDD 연관 관계 전략 (0) | 2025.12.09 |
|---|