본문 바로가기

Spring

👐 OSIV(Open Session In View)

OSIV를 만나게 된 이유?

이동욱님의 글을 보면서 배포 환경을 구축했다.

"JPA 사용시 OSIV 옵션은 끌것" 이라는 문구가 있었다.

OSIV (...?)

설정을 하더라도 이게 뭔지는 알아야 한다고 생각해서 OSIV에 대해 알아봤다.

OSIV란?

Spring Boot에서는 Default로Open Session In View를 true로 설정하고 있다고 한다. OSIV는영속성 컨텍스트를 뷰 렌더링이 끝나는 시점까지 개방한 상태로 유지한다는 의미이다. 그렇다면 왜 등장하게 되었을까?

등장하게 된 이유?

OSIV가 등장하게된 이유는 View 레이어에 연관된 객체를 사용하면,LazyInitializationException이 발생하게 되는데 이 부분에 대해 예제로 알아보자.

findAll 메서드를 사용한다고 가정해보자. 메서드가 종료되면 아래와 같이 일어난다.

  1. Transaction 종료
  2. JDBC Connection disconnect
  3. Hibernate Session 종료
  4. 영속 객체는 Detached 상태가 된다.

Detached는 데이터베이스 식별자를 가지지만, 영속성 컨텍스트로부터 분리되었기 때문에 데이터베이스와 동기화가 보장되지 않는 상태를 의미한다. 즉, Service 레이어에서 관리되는 Transaction이 View 레이어로 넘어가면서 종료되었기 때문에 LazyInitializationException이 발생하게 된다.

OSIV는 뷰 렌더링 시점에 Detached 상태의 객체의 프록시를 초기화 할 수 없다.
따라서 뷰 렌더링 시점까지 영속성 컨텍스트를 유지하여, 작업 단위를 요청 시점부터 뷰 렌더링까지 확장하기 위해 사용하기 위해 OSIV가 등장했다.

OSIV는 좋은게 아닌가?

OSIV 패턴을 적용한다면 LazyInitializationException 문제가 발생하지 않는다. 물론 예외를 막을 수 있기 때문에 장점이라고 생각할 수 있다. 하지만 Transaction의 범위가 커지게 되면, 그 만큼 DB 커넥션을 붙잡고 있어야 한다.

커넥션을 붙잡고 있다는 것은 성능 이슈의 주 원인되기도 한다.

정리

OSIV는 Spring Boot에서 Default로 true로 설정되어 있다. 하지만 View 까지 DB 커넥션을 붙잡고 있으면 성능 이슈의 주 원인이 되기도 해서 false로 설정해주자.

그리고 레이어 아키텍처를 생각하면 뷰 레이어까지 트랜잭션이 지속되어야 하는게 맞나?

뷰 레이어에서 객체를 사용하는게 맞나? 의심해보자.