View 영역은 일반적으로 생각하는 Controller 영역이나 뷰 영역(jsp, thymeleaf) 영역을 의미한다.
Controller나 뷰 영역에도 영속성 컨텍스트를 유지한다는 것
영속성 컨텍스트의 범위는?
영속성 컨텍스트는 엔티티 매니저와 연관이 깊다.
엔티티 매니저가 생성되는 시점에 생성되고 엔티티 매니저가 종료되는 시점에 소멸한다. 트랜잭션 매니저를 별도로 구현하지 않고 @Transactional 애너테이션을 사용한다면 애너테이션이 붙어있는 메서드 영역 내에서 영속성 컨텍스트가 생성되고 소멸되는 것으로 이해할 수 있다.
영속성 컨텍스트의 범위를 확장해야 하는 이유?
@Transactional 애너테이션은 보통 Service 레이어에서 많이 사용하는데 Service 레이어가 아닌 컨트롤러나 뷰 영역에서도 영속성 컨텍스트가 필요한 경우가 있을 수 있지만 많이 경험하지 못하였을 것이다.
대부분 DTO를 사용하기 때문
컨트롤러 영역에서 필요한 DTO 모델을 생성하여 Dao에서 내려받은 결과값을 DTO에 바인딩 해주기 때문에 OSIV를 고려해야하는 경우가 많지 않았을 것이다.
하지만 몇년 전까지만 하더라도 JPA를 사용하면 엔티티를 그대로 모델로 사용하는 경우가 많았고 컨트롤러, 뷰 영역에서도 엔티티를 조작하는 경우가 발생
뷰 영역에서 엔티티를 수정할 경우 DB반영이 될 까?
트랜잭션을 사용하는 서비스 계층이 끝날 때 트랜잭션이 커밋되면서 이미 플러시를 했기 때문에 스프링이 제공하는 OSIV 서블릿 필터나 OSIV 스프링 인터셉터는 요청이 끝나면 플러시를 호출하지 않고 em.close()로 영속성 컨텍스트만 종료해 버리므로 플러시가 일어나지 않는다. 만약 뷰 영역에서 em.plush()를 강제로 호출해도 트랜잭션 범위 밖이라는 예외가 발생하게 될 것이다.
OSIV On
최초 데이터베이스 커넥션 시작 시점부터 api 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다.
api컨트롤러에서 지연 로딩이 가능
지연로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지한다. 이것이 큰 장점
너무 오랜시간 데이터베이스 커넥션 리소스를 사용하기 때문에 실시간 트랙픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있다.
OSIV Off
트랜잭션을 종료하는 시점에서 영속성 컨텍스트를 닫고, 데이터 베이스 커넥션도 반환한다. 따라서 커넥션 리소스를 낭비하지 않는다.