[Spring/JPA] OSIV 전략이란? 언제 사용해야 할까?

반응형

OSIV (Open Session In View)

OSIV란 스프링 프레임워크에서 사용하는 세션 관리 전략 중 하나로 스프링 부트에서는 기본 값이 True로 설정되어 있다.

여기서 세션 (Session)은 하이버네이트의 세션. 즉, 영속성 컨텍스트를 뜻한다.

용어를 그대로 해석하면, "View까지 영속성 컨텍스트를 열어 둔다"로 해석할 수 있고

이는 영속성 컨텍스트가 View까지 살아 있도록 하는 것이다.

 

spring.jpa.open-in-view: true

영속성 컨텍스트는 트랜잭션의 생명 주기와 동일하다.

하지만 이 옵션이 true로 설정된다면, 영속성 컨텍스트의 생명주기를 View에 응답이 갈 때 까지 유지시킨다.

기본이 true이기 때문에 따로 설정을 하지 않았다면 Lazy 로딩을 사용했을 때

트랜잭션 범위를 벗어나고 프록시 객체에 접근한다하더라도 LazyInitializationException 이 발생하지 않는 것을 볼 수 있다.

 

애플리케이션에서 HTTP 요청마다 새로운 데이터베이스 커넥션이 생성되는데

이에 따라 많은 수의 DB 커넥션이 발생하여 성능 저하가 발생할 수 있다.

데이터베이스의 커넥션은 무한하지 않고 한정적이다.

true일 경우 API 응답이 끝날 때 까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지기 때문에

요청이 빈번한 서비스에서는 이 옵션을 고려할 필요가 있다.

 

장점

지연 로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지한다.

때문에, 지연 로딩을 사용할 때 트랜잭션 범위를 고려하지 않고 간편하게 코드를 작성할 수 있다.

 

단점

컨트롤러에서 API를 호출 할 때 10초가 걸리면, 10초 동안 커넥션을 반환하지 못하고 유지해야 한다.

즉, 너무 오랜시간 데이터베이스 커넥션을 사용하여, 실시간 트래픽이 중요한 서비스일 경우 커넥션이 부족해 시스템 장애로 이어질 수 있다.


spring.jpa.open-in-view: false

false로 설정하면 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환한다.

 

장점

커넥션 리소스를 낭비하지 않는다.

 

단점

지연 로딩은 영속성 컨텍스트가 살아 있어야 하는데, 영속성 컨텍스트가 닫혔기 때문에 모든 지연로딩을 트랜잭션 안에서 처리해야 한다.

지연로딩을 사용하는 상태에서 OSIV를 끄고 실행하면 LazyInitializationException 이 발생한다.

 

이 경우 지연 로딩 코드를 트랜잭션 안에서 처리하고 반환하거나, fetch join을 사용해 해결해야 하는 등

지연 로딩 사용에 주의해줘야 할 부분이 생긴다.


언제 사용해야할까?

OSIV가 true면 지연 로딩을 사용하는게 편리하고, false면 커넥션 문제가 해결 되지만 지연 로딩을 사용하는데 추가 작업이 필요하다.

 

그럼 언제 OSIV를 사용해야 할까?

  • 요청이 많지 않은 간단한 서비스나 커넥션을 많이 사용하지 않은 곳에서는 true
  • 고객 서비스 실시간 API는 false (ex: 채팅 기능)

참고자료 : JPA 활용 2 - API 개발과 성능 최적화