[김영한님의 실전! 스프링 부트와 JPA 활용2 강의 학습 후 정리한 내용입니다.]
OSIV란?
OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어두는 기능이다. JPA에서는 OEIV(Open EntityManager In View), Hibernate에서는 OSIV(Open Session In View)라고 하는데, 관례상 둘 다 OSIV라고 부른다. 개발자는 OSIV를 임의로 켜거나 끌 수 있기 때문에 서비스 특성에 맞게 OSIV 전략을 활용할 필요가 있다. 아래에서 자세히 알아보자.
OSIV on
- spring.jpa.open-in-view : true (기본값)
- 영속성 컨테이너를 뷰까지 열어두게 되면 트랜잭션이 끝나는 컨트롤러 계층에서도 지연 로딩(Lazy Loading)이 가능하기 때문에 이를 위해 사용한다.
- 뷰 템플릿이나 API컨트롤러에서 지연 로딩을 해서 데이터를 불러오는 작업을 했던 것도, 바로 OSIV를 켰기 때문에 가능한 것이다.
동작 원리는 다음과 같다.
- 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스트를 생성한다. 이 시점에서는 트랜잭션이 시작되지 않는다.
- 서비스 계층에서 @Transactional로 트랜잭션을 시작하게 되면 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아온다.
- 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 flush한다.
- 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지한다.
- 서블릿 필터나, 스프링 인터셉터로 요청이 들어오면 영속성 컨텍스트를 종료한다. 이 때, flush를 하지 않고 바로 종료한다.
OSIV ON 전략은 오랜시간 동안 데이터베이스 커넥션 리소스를 사용하기 때문에, 실시간 트래픽이 중요한 애플리케이션에는 커넥션이 모잘랄 수 있다는 단점이 있다. ex) 컨트롤러에서 외부 API를 호출하게 되면 외부 API 대기 시간만큼 데이터베이스 리소스를 반환하지 못한다.
OSIV OFF
- spring.jpa.open-in-view: false
- 위 그림을 보면, OSIV를 켰을 때와 달리 영속성 컨텍스트의 생존 범위가 트랜잭션 범위와 같아지는 것을 볼 수 있다. 즉, 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환된다.
- 따라서 우리가 컨트롤러 계층에서 사용했던 모든 지연 로딩을 트랜잭션 안에서 처리되도록 해야 한다는 단점이 있다.(이를 위해 API개발을 위한 Service계층을 따로 만들어서 구현할 수 있을 것이다.)
정리
OSIV를 켜야할까 꺼야할까?
OSIV를 키면 데이터베이스 커넥션 이슈가 있긴 하지만 지연 로딩을 컨트롤러나 뷰 템플릿에서 처리하면 되기 때문에 개발이 쉽고, 유지 보수에 용이하다. 하지만 성능을 신경 쓴다면, OSIV를 꺼야한다. 예를 들어서 고객 서비스의 실시간 API를 개발 하고 있다면, OSIV를 끄고 ADMIN처럼 커넥션을 많이 사용하지 않는 곳에서는 OSIV를 키는 것처럼 말이다.
Reference: https://ykh6242.tistory.com/entry/JPA-OSIVOpen-Session-In-View와-성능-최적화
'ORM > JPA' 카테고리의 다른 글
[JPA] 연관관계 매핑 기초 (0) | 2023.04.24 |
---|---|
[JPA] 엔티티 매핑 (0) | 2023.04.24 |
[JPA] 컬렉션 조회 최적화 (0) | 2023.04.17 |
[JPA] 지연 로딩과 조회 성능 최적화 (0) | 2023.04.16 |
[JPA] 더티 체킹(dirty checking) 정리 (0) | 2023.04.16 |
댓글