본문 바로가기

Spring 정리/Spring JPA

OSIV

728x90
반응형

개요


JPA는 구현체를 Hibernate로 가지고 있습니다. QueryDsl 등을 통해서 쿼리문을 만드는 등 여러 추상화 기술을 이용하고 있기 때문에, 성능 상 조심해야 하는 점들이 있습니다. 그 중에 오늘은 OSIV에 대해 알아보겠습니다. 평소에 별로 고려하지 않았던 부분인데 실시간 서비스에서는 성능 상 이슈는 낼 수 있다는 것을 알고 공부하게 됐습니다.

 

 

OSIV란?


 OSIV는 Open Session In View 의 약자로, 직역하면 View에서도 계속 Session이 Open 되어 있다는 뜻입니다. 즉, 사용자에게 보여지는 화면에서도 세션이 계속 유지됩니다. 비록 트랜잭션이 끝나도 말입니다. 트랜잭션에 관해서는 아래에서 설명하겠습니다.

 

 

OSIV을 잘 이해하기 위해서 요청이 들어온 상황을 가정해보겠습니다.

1. 스프링은 요청이 오면 새로운 하이버네이트 세션을 시작합니다. 
(이 세션들이 데이터베이스에 필수로 연결 되어야 하는 건 아닙니다.)

2. 애플리케이션이 세션이 필요 할 때, 이미 존재하는 세션이 있다면 재사용 합니다.

3. 요청이 끝날 즈음에, 같은 인터셉터는 세션을 종료합니다.

 

원래는 @Transactional이 붙어있는 서비스 레이어가 종료되면, 세션도 같이 종료됩니다.

하지만, OSIV는 세션 라이프 사이클을 요청에 결합시키기 때문에, 요청을 받은 시점부터 요청 작업이 모두 끝날 때까지 세션이 유지됩니다. (이를 앞으로 영속성 컨텍스트가 생존한다고 표현하겠습니다.)

 

영속성 컨텍스트가 계속 생존하기 떄문에 @Transactional이 붙어있는 서비스 레이어가 종료되어도, Controller나 View에서 지연로딩을 지원합니다.

 

영속성 컨텍스트의 범위와 트랜잭션의 범위는 아래와 같습니다.

 

 

 

 

OSIV를 사용하지 않는다는 것은, 생성된 세션의 영속성 컨텍스트를 요청의 라이프 사이클에 묶지 않고, 트랜잭션 범위에만 한정시킨다는 의미입니다. 

 

 

OSIV의 ON/OFF의 차이를 사진으로 비교했으니 장점과 단점을 알아보겠습니다.

 

주의 할 것은, @Transactional을 삭제해도 OSIV를 ON으로 해두면, @Transactional과 관계없이 영속성 컨텍스트의 라이프 사이클은 요청과 묶여져서 성능 상 이슈를 낼 수도 있습니다.

 

 

OSIV의 장점과 단점


  • 장점

Controller나 View에서 지연로딩이 가능해서 쿼리문을 좀 더 쉽게 작성할 수 있습니다.

Service layer를 벗어난 곳에서도 추가적인 DB 작업을 할 수 있습니다.

 

  • 단점

모든 요청이 끝날때까지 DB 커넥션을 가지고 있어 성능 상 문제가 발생할 수 있습니다.

만약 DB 커넥션을 가진 상태에서 원격 호출이 지연된다면 커넥션이 부족해질 수 있습니다.

 

 

 

OSIV를 언제 사용해야 할까?


결론적으로는 각 프로젝트의 성격에 따라서 달리 사용해야 합니다.

 

OSIV를 사용하겠다는 의미는, @Transactional이 끝난 이후에도, Controller난 View까지 계속 DB 커넥션을 유지하겠다는 것과 같은 의미입니다. 따라서 DB 커넥션이 많아지기 때문에 실시간으로 고객들에게 보여지는 API, 화면에서는 OSIV를 OFF로 해야 DB 커넥션을 넉넉하게 확보 할 수 있습니다. 어드민 페이지거나 트래픽 유입이 그닥 높지 않을 것으로 기대되는 곳에는 OSIV를 ON으로 해도 괜찮습니다.

 

 

OSIV는 스프링에서 기본적으로 true로 되어 있습니다.

 

spring.jpa.open-in-view=true

 

 

만약에 OSIV를 사용하고 싶지 않다면 false를 설정해야 합니다.

 

단, @Transactional 메서드 실행 이후에 지연로딩을 하는 작업이 있었다면, 해당 작업을 별도의 클래스로 빼는 것을 고려해야 합니다. 예를들어, StudyController에서 지연로딩이 있었다면, 모든 과정을 StudyQueryService로 모아서 하나의 @Transactional 안에 묶어두어야 합니다. 

 

 

참고

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

https://www.baeldung.com/spring-open-session-in-view

728x90
반응형