OSIV (Open Session In View)

OSIV가 켜져있을 경우의 영속성 컨텍스트 생존 범위

 

  • JPA는 트랜잭션이 시작될 때 데이터베이스 커넥션을 가져온다.
  • osiv가 켜져있으면,트랜잭션이 끝나도 데이터베이스 커넥션을 반환하지 않는다(영속성 컨텍스트를 살려둔다).
  • 뷰의 경우 데이터가 렌더링 되고 나서, API의 경우 응답이 요청에 완전히 반환되는 등 모든 작업이 완전히 끝이 나야 돌려준다.
  • 이러한 osiv가 default로 true 이기 때문에, View Template이나 API 컨트롤러에서도 지연 로딩이 가능했던 것.
  • 지연 로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 데이터베이스 커넥션을 유지한다.
  • 이렇게 유용하지만, 데이터베이스 커넥션 리소스를 너무 오랫동안 붙들고 있기 때문에 실시간 트래픽이 중요한 경우 커넥션이 모자랄 수 있고 장애로 이어진다.
  • 즉, 외부 API 호출을 하면 외부 API 응답 대기 시간 만큼 커넥션 리소스를 반환하지 못하는 것.

 

 

OSIV가 꺼져있을 경우 영속성 컨텍스트 생존 범위

 

  • osiv가 꺼져있으면, 트랜잭션이 종료되면 영속성 컨텍스트를 닫고 데이터베이스 커넥션도 반환한다.
  • 따라서 모든 지연로딩은 트랜잭션 안에서(Service, Repository) 처리되어야 한다.
  • 그래서 이 환경에서는 자연스럽게 Command(변경)와 Query(조회)의 분리 설계가 필요해진다.

 

커맨드와 쿼리

Command (변경용)

  • Entity 중심
  • 영속성 컨텍스트 필요
  • 트랜잭션 안에서 데이터 변경

Query (조회용)

  • OSIV OFF 환경에 맞게
  • DTO 전용 조회
  • Lazy 로딩 사용 안 함
// 구조 예시

OrderService (Command)
- cancel()
- changeAddress()

OrderQueryService (Read API)
- findOrderListDto()
- findOrderDetailDto()
  • 즉, 조회는 조회답게, 변경은 변경답게 역할 분리
  • 복잡한 화면 요구사항에 따라 조회 쿼리가 변하는 것은 자연스러운 일이지만, 그 변화가 도메인 모델에까지 영향을 주기 시작하면 시스템은 무너진다.
  • 따라서 도메인은 비즈니스 규칙만 책임지고, 조회 최적화는 별도의 조회 계층이 감당하도록 분리해야 한다.
도메인 = 의미와 규칙
조회 = 표현과 성능

→ 목적이 다르면 구조도 달라야 한다 

 

복잡한 조회 때문에 도메인을 변형시키면, 시스템 설계가 무너진다.