Java/JPA

OSIV(OpenSessionInView)

뽀루피 2024. 8. 27. 16:36

OpenSessionInView (기본값 true)

JPA에서는 EntityManager로 DB 커넥션을 유지하지만 JPA의 전신인 Hibernate에서는 Session으로 유지하기에 이름이 이렇게 붙었다.

 

 

True

 

true인 경우, 최초의 DB 커넥션 시작 시점부터 API 응답이 끝날 때까지 영속성 컨텍스트와 DB 커넥션을 유지한다. 그래서 OSIV 설정을 따로 변경안했을 때 View Template이나 Controller에서 지연로딩이 가능했던 것이다(1차 캐시 유지). 하지만 현업에서는 이를 False로 막아놓는다. 이유가 뭘까?

 

그 이유는 API에 블록킹이나 연결이 길어지는 이슈가 생긴다면 DB 커넥션 리소스가 말라버리기 때문이다. 실시간 트래픽이 중요한 애플리케이션에서는 커넥션 리소스가 부족해질 수 있고 이는 장애로 이어진다.

 

 

 

False

 

yaml 파일에서 spring.jpa.open-in-view: false로 설정할 수 있다. OSIV를 끄면 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, DB 커넥션도 반환한다. 이로써 DB 커넥션 리소스를 절약할 수 있는데, 모든 지연로딩 전략을 트랜잭션 내에서 처리해야 한다. 트레이드 오프이다. 그렇다고 Controller의 모든 로직을 Service단으로 옮겨버리면 관심사 분리 원칙이 망가진다. Controller나 ViewTemplate의 코드는 화면에 따라 성능을 최적화 하는 것이 중요하다. 반면 비지니스 로직에 큰 영향을 주지 않는다. 그래서 크고 복잡한 애플리케이션을 개발할 때는 둘의 관심사를 분리해주는 것이 좋다.

 

  • OrderService 예시 
    • OrderService
    • OrderQueryService

OrderQueryService는 Controller에 들어간 화면 로직을 Service계층으로 옮긴 클래스이다. 보통 서비스 계층에서 트랜잭션을 유지하므로 이렇게 분리한다면 두 서비스 모두 트랜잭션을 유지하면서 지연로딩을 사용할 수 있다.

 

결론적으로 고객 서비스의 실시간 API는 OSIV를 끄고, ADMIN 처럼 커넥션을 많이 사용하지 않는 곳에서는 OSIV를 키는 것이 좋다.

'Java > JPA' 카테고리의 다른 글

Fetch Join(2) - xToOne과 xToMany의 차이  (0) 2024.08.27
ddl-auto: create 적용 안되는 문제  (0) 2024.02.04