OSIV란?

이수찬·2023년 4월 9일
0

OSIV : Open Session In View 란 기존에 hibernate에서 session을 관리하는 전략으로,
JPA에서 데이터베이스 커넥션과 영속성 컨텍스트의 생명주기를 관리하는 전략이다.
JPA에서의 Open Session In View 는 Open EntityManager In View지만, 관례상 OSIV라 부른다.

spring에서는 다음과 같이 OSIV가 작동하는 것을 볼 수 있다.

WARN 15712 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

위와 같이 spring.jpa.open-in-view로 OSIV를 부르고 있으며,
WARN 을 통해 경고 메세지를 보내고 있다.

경고 메세지는 SpirngBoot에서 OSIV를 default로 true로 설정하고 있는데, 이는 성능적인 측면에서 볼때, 부적절한 것으로 OSIV를 false로 설정할 것을 추천하고 있다.

그렇다면 언제 OSIV를 true로 하고, 언제 OSIV를 false로 해야할까?
먼저 OSIV란 무엇인지 먼저 알아보자.

  1. OSIV란?

OSIV는 데이터베이스 커넥션과 영속성 컨텍스트를 관리하는 전략이다.
OSIV를 true로 설정해두면, 다음과 같이 적용된다.

기본적으로 OSIV설정을 켜두면, @Transactional 시작시 데이터베이스 커넥션을 연결하고, 영속성 컨텍스트를 생성한다.
해당 전략에서는 트랜잭션 시작과 함께 DB커넥션과 영속성 컨텍스트가 생성되며, 클라이언트에게 response를 반환할 때까지 영속성 컨텍스틑 유지한다.
그렇기에 트랜잭션이 종료된 이후에도, 영속성 컨텍스트가 존재하여, controller 단에서도 Lazy Loading이 가능하다.

다음은 OSIV를 false로 설정해둘 때이다.

OSIV 전략을 false로 한다면, OSIV를 true로 설정할 때와 동일하게 트랜잭션 시작시 데이터베이스 커넥션을 연결하고, 영속성 컨텍스트를 생성하지만, 트랜잭션 종료 시점에 영속성 컨텍스트를 종료하고, 데이터베이스 커넥션을 해제한다.
그렇기에 트랜잭션이 종료된 이후에는 Lazy Loading이 불가능하다.
(영속성 컨텍스트가 존재할 때만 Lazy Loading이 가능하기 때문)

  1. OSIV false 시 지연로딩 사용

OSIV를 false로 설정해두고, 트랜잭션 종료후에 지연로딩을 사용하면 다음과 같은 예외 메세지 나타난다.

LazyInitializationException: failed to lazily initialize a collection of role:
could not initialize proxy - no Session

위의 예외 메세지를 살펴보면, 세선이 존재하지 않아 프록시를 초기화할 수 없다고 하는데, 영속성 컨텍스트가 트랜잭션 종료시에는 존재하지 않아 지연로딩에서 사용하는 프록시 초기화를 사용할 수 없어 지연로딩이 불가능한 것을 볼 수 있다.

  1. OSIV false 설정

다음과 같이 yml파일에 open-in-view를 false로 설정해주면 된다.

  jpa:
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        show_sql: true
        format_sql: true
    open-in-view: false
  1. OSIV 설정의 장단점

open-in-view: true

  • 장점 : 데이터베이스 커넥션 시작시점부터 API 응답이 끝날때까지 영속성 컨텍스트와 데이터 베이스 커넥션을 유지하기에 view단에서도 영속성 컨텍스트를 사용할 수 있다.
  • 단점 : 데이터베이스 커넥션을 너무 오랜 시간 사용해, 실시간 트래픽이 중요한 애플리케이션에서는 커넥션 풀의 커넥션이 부족해 질 수 있다. (ex. API 대기시간 동안 커넥션 풀 사용)

open-in-view: false

  • 장점 : 트랜잭션 종료시 데이터베이스 커넥션과 함께 영속성 컨텍스트도 종료되기에, 커넥션 리소스를 낭비하지 않는다.
  • 단점 : 트랜잭션 종료시 모든 지연로딩을 트랜잭션 안에서 처리해야 한다.

=> 결국 커넥션이 많이 필요한 곳은 OSIV설정을 끄고, 커넥션이 많이 사용되지 않는 곳은 OSIV설정을 켜자.

  1. Commend와 Query를 분리

핵심 비즈니스 로직과 화면이나 API에 맞춘 서비스를 분리하여 사용함으로써 트랜잰션안에서 모든 지연로딩을 처리하고, 관심사를 명확히 나눠 유지보수를 용의하게 할 수 있다.

<참고자료>
: 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-API%EA%B0%9C%EB%B0%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94/dashboard

0개의 댓글