[JPA] OSIV

6720·2023년 12월 14일
0

이거 모르겠어요

목록 보기
36/38

OSIV

Open Session In View

영속성 컨텍스트를 뷰까지 열어두는 기능
영속성 컨텍스트가 유지되면 엔티티도 영속 상태로 유지됨.
뷰까지 영속성 컨텍스트가 살아있다면 뷰에서도 지연 로딩을 사용할 수 있음.

영속성 컨텍스트 관련 포스팅


+) JPA에서는 OEIV(Open EntityManager In View), hibernate에서는 OSIV라고 함.

동작 원리

스프링 프레임워크가 제공하는 OSIV는 비즈니스 계층에서 트랜잭션을 사용하는 OSIV임.
영속성 컨텍스트는 사용자의 요청 시점에서 생성이 되지만, 데이터를 쓰거나 수정할 수 있는 트랜잭션은 비즈니스 계층에서만 사용할 수 있도록 트랜잭션이 일어남.

  • 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스트를 생성함.
  • 서비스 계층에서 @Transactional로 트랜잭션을 시작할 때 미리 생성해둔 영속성 컨텍스트를 가져와서 트랜잭션을 시작함.
  • 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 flush함. 이 시점에 트랜잭션을 끝내지만 영속성 컨텍스트는 종료되지 않음.
  • 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지함.
  • 서블릿 필터나, 스프링 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료함. 이때 flush를 호출하지 않고 바로 종료함. -> 지연 로딩을 사용할 수 있던 이유

트랜잭션이 종료된 이후에도 엔티티를 변경 없이 단순 조회가 가능함. 이를 트랜잭션 없이 읽기(Nontransactional reads)라고 함.

트랜잭션 범위 밖인 컨트롤러와 뷰에서 엔티티를 수정하여도 영속성 컨텍스트의 변경 감지에 의한 데이터 수정이 동작되지 않음.

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하려면 영속성 컨텍스트를 flush해야 함. 스프링이 제공하는 OSIV는 요청이 끝나면 flush를 호출하지 않고 영속성 컨텍스트만 종료시켜 버림(em.close()).
  • 프레젠테이션 계층에서 강제로 flush를 호출(em.flush())해도 트랜잭션 범위 밖이므로 데이터를 수정할 수 없다는 예외가 일어남. TransactionRequiredException

장점 및 단점

장점

  • 프록시를 초기화하는 작업을 서비스 계층에서 끝내지 않고도 렌더링 시 자동으로 해결하게 해줌.
  • 지연 로딩을 사용할 수 있음.
    • 지연 로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지함.

단점

오랜시간 데이터베이스 커넥션을 사용한다는 단점도 있음. 커넥션 리소스를 오래 사용하기 때문에 커넥션이 모자랄 수 있음. 이는 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 말라버렸다고 표현하며, 곧 시스템 장애임.
-> 커넥션을 영속성 컨텍스트가 종료될 때까지 1:1로 계속 물고 있음.

OSIV OFF

spring.jpa.open-in-view: false

true가 기본이기 때문에 OSIV를 끄고 싶다면 false로 해줘야 함.

만약 끄게 된다면 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환함. -> 커넥션 리소스를 낭비하지 않음.

단, 모든 지연 로딩을 트랜잭션 안에서 처리해야 함.
개발 도중에 OSIV를 끄게 된다면 많은 지연 로딩 코드를 트랜잭션 안으로 넣어야 함.
또, view template에서 지연 로딩이 동작하지 않음.
-> 트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해 둬야 함.

복잡성 관리

OSIV를 끈 상태로 복잡성을 관리하는 좋은 방법은 커맨드와 쿼리를 분리하는 것임.

보통 비즈니스 로직은 특정 엔티티 몇 개를 등록하거나 수정하는 것이므로 성능이 크게 문제되지 않음.
하지만 복잡한 화면을 출력하기 위한 쿼리는 화면에 맞추어 성능을 최적화 하는 것이 중요함.
하지만 그 복잡성에 배히 핵심 비즈니스에 큰 영향을 주는 것은 아님.
-> 이 둘의 관심사를 명확하게 분리하여야 함.

참고 자료

profile
뭐라도 하자

0개의 댓글