여태까지 JPA를 사용하면서 서버를 시작할 때마다 만났던 warning 로그이다.
구글링을 통해 대충 무엇인지 개념 정도만 알고 있었는데, 강의를 보던 중 이 내용을 다루는 부분이 있었다.
OSIV 전략
은 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날 때 까지 영속성 컨텍스트와 DB 커넥션을 유지하는 것이다.
기본값은 true
이며, true로 설정할 시 View Template이나 컨트롤러까지 영속성 컨텍스트가 유지되기 때문에, 여기에서 수행되는 지연로딩이 정상적으로 수행된다.
지연 로딩이라는 것은 영속성 컨텍스트
가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션
을 유지하기 때문에, 컨트롤러 단에서 지연로딩을 사용할 수 있다는 것은 장점으로 다가올 수 있다.
OSIV를 끄면(false 설정)
트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환한다. 따라서 지연 로딩을 수행하는 코드들은 모두 트랜잭션 안에서 호출
해두어야 한다.
만일 이대로 설정해두고 트랜잭션 바깥에서 지연로딩을 호출한다면
could not initialize proxy - LazyInitializationException
이 발생할 것이다.
영속성 컨텍스트 바깥에서 지연로딩이 호출됐기 때문에, 생성해두었던 proxy 객체를 초기화할 수 없다는 에러이다.
이렇게만 보면 OSIV를 켜두는 것이 좋다고 생각될 수 있다.
하지만
이 전략은 너무 오랜시간동안 데이터베이스 커넥션 리소스를 사용하기 때문에, 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있고, 이것은 결국 장애로 이어질 수 있다.
예를 들어서 컨트롤러에서 외부 API를 호출하면 외부 API 대기 시간 만큼 커넥션 리소스를 반환하지 못하고 유지
해야 한다
그럼 켜두는 것과 끄는 것 어떤 게 좋은 방법일까?
단순히 편리성
을 생각한다면 켜두는 것도 좋은 방법이지만, 성능
을 생각해야 한다면 꺼두는 것이 좋다.
따라서 트래픽이 많고 성능 최적화가 중요한 애플리케이션에서는 OSIV를 꺼두는 편이 좋지만, ADMIN 환경 처럼 커넥션을 많이 사용하지 않는 곳에서는 OSIV를 켜두는 편이 좋다.
만일 OSIV를 꺼둔다면 영속성 컨텍스트의 범위를 잘 생각하고 개발해야 하기 때문에 고려해야 할 점이 몇 가지 있다.
예를 들어, 서비스에서 Entity를 뱉을 경우 생길 수 있는 문제점 등을 잘 고려해야 한다.
OSIV = false 일때는 영속성 컨텍스트가 Service까지만 유지되는데, Controller에 Entity를 뱉을 경우
응답 Dto로 변환 시에 LazyInitializationException이 발생
할 수 밖에 없다.
자료 출처 : 김영한님의 스프링부트와 JPA 활용 2편