OSIV와 Transaction 경계
Web 요청 끝까지 Persistence Context를 유지할지 Service Transaction까지만 유지할지 결정한다.
이 문서의 목차
Overview
OSIV는 Web 요청이 끝날 때까지 Persistence Context를 열어 Controller와 View에서도 Lazy Loading을 허용하는 정책이다. Transaction이 끝난 것과 Persistence Context가 닫힌 것은 같은 사건이 아니다.
OSIV ON
Service Transaction이 끝난 뒤에도 EntityManager가 요청 범위에 남아 Controller의 Lazy Loading이 가능하다. 개발은 편하지만 뒤늦게 발생하는 Query가 API Layer에 숨고, 외부 API 대기 중 Connection 점유 시간이 길어질 수 있다.
OSIV OFF
Transaction이 끝나면 Persistence Context 범위도 끝난다. 필요한 연관관계를 Service 안에서 조회하고 DTO로 변환해야 한다. 경계 밖 Lazy Loading은 LazyInitializationException으로 드러난다.
spring:
jpa:
open-in-view: falseflowchart LR; A[Controller] --> B[Service Transaction]; B --> C[Repository/DB]; B --> D[DTO 변환]; D --> E[Controller 응답]; C -. OSIV ON 시 지연 조회 .-> E
Query Service 분리
복잡한 화면 Query는 읽기 전용 Query Service에서 Transaction 안에 조회와 DTO 변환을 끝낸다. Command Service와 조회 최적화의 변경 이유를 분리하면서 Controller에 Entity를 노출하지 않는다.
실무에서 발생하는 문제
- Controller 직렬화가 예상하지 못한 Lazy Query를 연쇄 실행한다.
- 외부 API 호출과 Rendering 동안 Connection을 오래 점유한다.
- OSIV를 끈 뒤 DTO 변환 위치를 정하지 않아 곳곳에서 LazyInitializationException이 발생한다.
- Admin과 대규모 Traffic API에 같은 정책을 기계적으로 적용한다.
Trade-off
ON은 개발 편의와 유연한 Lazy Loading을, OFF는 명확한 Query/Resource 경계를 제공한다. Traffic, Connection Pool, API 응답 Model과 Team의 Query 관리 방식을 기준으로 선택한다.
Interview Questions
- Transaction 종료와 Persistence Context 종료는 왜 다를 수 있는가?
- OSIV ON에서 Connection 점유 시간이 길어지는 경로를 설명하라.
- OSIV OFF에서 Lazy Loading이 필요한 DTO를 어디서 구성할 것인가?
- Query Service 분리가 해결하는 책임 문제는 무엇인가?
Related Topics
Lazy Loading과 N+1, Connection Pool, Persistence Context를 함께 확인한다.
SOURCE REFERENCES
이 문서의 근거
본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.