Open Session In View
영속성 컨텍스트를 뷰까지 열어두는 기능
영속성 컨텍스트가 유지되면 엔티티도 영속 상태로 유지됨.
뷰까지 영속성 컨텍스트가 살아있다면 뷰에서도 지연 로딩을 사용할 수 있음.
+) JPA에서는 OEIV(Open EntityManager In View), hibernate에서는 OSIV라고 함.
스프링 프레임워크가 제공하는 OSIV는 비즈니스 계층에서 트랜잭션을 사용하는 OSIV임.
영속성 컨텍스트는 사용자의 요청 시점에서 생성이 되지만, 데이터를 쓰거나 수정할 수 있는 트랜잭션은 비즈니스 계층에서만 사용할 수 있도록 트랜잭션이 일어남.
트랜잭션이 종료된 이후에도 엔티티를 변경 없이 단순 조회가 가능함. 이를 트랜잭션 없이 읽기(Nontransactional reads)라고 함.
트랜잭션 범위 밖인 컨트롤러와 뷰에서 엔티티를 수정하여도 영속성 컨텍스트의 변경 감지에 의한 데이터 수정이 동작되지 않음.
TransactionRequiredException
장점
단점
오랜시간 데이터베이스 커넥션을 사용한다는 단점도 있음. 커넥션 리소스를 오래 사용하기 때문에 커넥션이 모자랄 수 있음. 이는 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 말라버렸다고 표현하며, 곧 시스템 장애임.
-> 커넥션을 영속성 컨텍스트가 종료될 때까지 1:1로 계속 물고 있음.
spring.jpa.open-in-view: false
true가 기본이기 때문에 OSIV를 끄고 싶다면 false로 해줘야 함.
만약 끄게 된다면 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환함. -> 커넥션 리소스를 낭비하지 않음.
단, 모든 지연 로딩을 트랜잭션 안에서 처리해야 함.
개발 도중에 OSIV를 끄게 된다면 많은 지연 로딩 코드를 트랜잭션 안으로 넣어야 함.
또, view template에서 지연 로딩이 동작하지 않음.
-> 트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해 둬야 함.
OSIV를 끈 상태로 복잡성을 관리하는 좋은 방법은 커맨드와 쿼리를 분리하는 것임.
보통 비즈니스 로직은 특정 엔티티 몇 개를 등록하거나 수정하는 것이므로 성능이 크게 문제되지 않음.
하지만 복잡한 화면을 출력하기 위한 쿼리는 화면에 맞추어 성능을 최적화 하는 것이 중요함.
하지만 그 복잡성에 배히 핵심 비즈니스에 큰 영향을 주는 것은 아님.
-> 이 둘의 관심사를 명확하게 분리하여야 함.