OSIV

Mina Park·2022년 10월 2일
0

1. 기본개념

  • Open Session In View: 하이버네이트
  • Open EntityManager In View: JPA
  • 관례상 OSIV라고 명명

2. OSIV ON


- spring.jpa.open-in-view: true (default)

  • 기본값을 뿌리면서 애플리케이션 시작 시점에 warn 로그가 남음
  • OSIV 전략은 트랜잭션 시작처럼 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지
  • 📌 (장점) 그래서 API 컨트롤러에서 지연로딩이 가능했던 것
    • 지연로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지함
  • 📌 (단점) 하지만, 너무 오랜시간 데이터베이스 커넥션 리소스를 사용하기 때문에, 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자라 장애가 발생할 수 있음
    • 예를 들어, 컨트롤러에서 외부 API를 호출하게되면 외부 API 대기시간만큼 커넥션 리소스를 반환하지 못하고 유지해야함

3. OSIV OFF


- spring.jpa.open-in-view: false

  • 📌 (장점) OSIV를 끄면 트랜잭션 종료시 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환. 따라서 커넥션 리소스 낭비 X
  • 📌 (단점) 하지만, 모든 지연로딩을 트랜잭션 안에서 처리해야함
    • 따라서 지금까지 작성한 모든 코드를 트랜잭션 안으로 넣어야하는 단점이 존재(Serive, Repository 계층 안으로 수정)
    • 결론적으로 트랜잭션이 끝나기전에 지연로딩을 강제로 호출해줘야 함
    • org.hibernate.LazyIntializationException 발생

4. 커멘드와 쿼리 분리

  • 실무에서는 OSIV 를 끈 상태로 이 방법을 통해 복잡성을 관리할 수 있음
  • 보통 비즈니스 로직은 특정 엔티티 몇개를 등록/수정하는 것이므로 성능이 크게 문제가 되지 않음
  • 하지만, 복잡한 화면을 출력하기 위한 쿼리는 화면에 맞추어 성능을 최적화할 필요가 있음
  • 유지보수성을 고려하여 크고 복잡한 애플리케이션 개발시에는 "비즈니스 로직"과 "화면 맞춤용"의 관심사를 명확하게 분리하는 것을 권장

    [예시] OrderSevice

    • OrderService: 핵심 비즈니스 로직
    • OrderQueryService: 화면이나 API에 맞춘 서비스(주로 읽기전용 트랜잭션 사용)
  • 보통 서비스 계층에서 트랜잭션을 유지

[참고] 고객서비스의 실시간 API는 OSIV를 끄고, ADMIN처럼 커넥션이 많지 않은 곳에서는 OSIV 켜는 방법을 권장(한 프로젝트라 하더라도 배포물이 다르므로 다르게 설정하여 사용)

0개의 댓글