OSIV (Open Session In View)
영속성 컨텍스트를 뷰까지 열어두겠다는 의미
OSIV는 하이버네이트에서 사용하는 용어로, JPA에서는 OEIV(Open EntityManager In View)
라고 하지만 다들 OSIV로 부른다
▶발전 과정
- 과거 OSIV - 요청 당 트랜잭션
OSIV의 가장 단순한 구현 방법은 클라이언트 요청이 들어오자마자 서블릿 필터 혹은 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 것
문제점
- 컨트롤러나 뷰 같은 프리젠테이션 계층이 엔티티를 변경할 수 있다
고객의 정보를 제공하는 기능을 만들었고, 화면상에는 보안을 위해 고객의 이름을 "XXX"처럼 변경해서 보여주어야 한다고 가정
Member member = memberService.getMember(id); member.setName("XXX"); model.addAttribute("member", member);
이런 코드를 작성 할 것이다.
당연히 화면상에는 XXX로 보여지겠지만 OSIV방식을 사용하였기 때문에 member 엔티티는 영속 상태
따라서, 변경감지가 작동해 Name이 XXX로 DB에 저장된다.
해결 방법
프리젠테이션 계층에서는 엔티티를 수정하지 못하게 막는 방법
- 엔티티를 읽기 전용 인터페이스로 제공
- 엔티티를 읽기 전용 메서드만 가진 Wrapper 클래스로 매핑
- DTO만 반환
이런 방법들은 코드량이 상당히 증가 한다는 단점들이 있다
따라서, 요즘에는 거의 사용하지 않는다
- 최근 OSIV - 비즈니스 계층 트랜잭션
문제점을 어느정도 보안해서 비즈니스 계층에서만 트랜잭션을 유지하는 방식의 OSIV를 사용하는데,
이것이 바로 스프링 프레임워크가 제공하는 OSIV다.
Spring 에서는 기본적으로 OEIV 설정이 되어 있다.
spring.jpa.open-in-view: true
종류
- 하이버네이트 OSIV 서블릿 필터
org.springframework.orm.hibernate5.support.OpenSessionInViewFilter - 하이버네이트 OSIV 스프링 인터셉터
org.springframework.orm.hibernate5.support.OpenSessionInViewInterceptor - JPA OEIV 서블릿 필터
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter - JPA OEIV 스프링 인터셉터
org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
OSIV를 사용하기는 하지만 트랜잭션은 비즈니스 계층에서만 사용한다
동작 원리
- 클라이언트 요청이 들어오면 서블릿 필터 혹은 스프링 인터셉터에서 영속성 컨텍스트를 생성
-> 이때 트랜잭션은 시작하지 않는다 - 서비스 계층에서 @Transactional로 트랜잭션을 시작할 때 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아와 트랜잭션 시작
- 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 플러시
-> 영속성 컨텍스트는 유지 - 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지
- 서블릿 필터나 스프링 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료
-> 플러시를 호출하지 않고 바로 종료
즉, 영속성 컨텍스트는 프레젠테이션 계층까지 살려두면서, 변경은 불가능하게 만든 것
정리
- 특징
- 클라이언트의 요청이 들어올 때 영속성 컨텍스트를 생성해서 요청이 끝날 때까지 같은 영속성 컨텍스트를 유지즉, 한 번 조회한 엔티티는 요청이 끝날 때까지 영속 상태를 유지
- 엔티티 수정은 트랜잭션이 있는 계층에서만 동작
트랜잭션이 없는 프리젠테이션 계층은 지연 로딩을 포함해서 조회만 가능
- 단점
- OSIV를 사용하면같은 영속성 컨텍스트를 여러 트랜잭션이 공유할 수 있다는 점을 주의
특히 트랜잭션 롤백시 주의 - 프리젠테이션 계층에서 지연 로딩에 의한 SQL이 실행
즉, 성능 튜닝시에 확인해야 할 부분이 넓어진다 - 너무 오랜시간 동안 데이터베이스 커넥션 리소스를 사용
따라서 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있으며, 이것은 결국 장애로 이어질 수 있다
- OSIV를 사용하면같은 영속성 컨텍스트를 여러 트랜잭션이 공유할 수 있다는 점을 주의
- 장점
- 컨트롤러에서도 지연로딩이 가능
즉, 유지보수성이 높아진다
- 컨트롤러에서도 지연로딩이 가능
참고- https://ttl-blog.tistory.com/183
[JPA] OSIV 란?
스프링에서 JPA를 사용하게 되면 스프링 컨테이너가 트랜잭션과 영속성 컨텍스트를 관리해주므로 애플리케이션을 손쉽게 개발할 수 있습니다. 당연하게도 이러한 JPA의 내부 동작원리를 모르고
ttl-blog.tistory.com
'CS' 카테고리의 다른 글
INDEX (인덱스) (0) | 2023.08.23 |
---|---|
naver.com을 치면 일어나는 일 (0) | 2023.08.23 |
캐시 (0) | 2023.08.16 |
쿠키 세션 토큰 (0) | 2023.08.10 |
JWT (0) | 2023.08.10 |