본문 바로가기

CS

OSIV

OSIV (Open Session In View)

영속성 컨텍스트를 뷰까지 열어두겠다는 의미

OSIV는 하이버네이트에서 사용하는 용어로, JPA에서는 OEIV(Open EntityManager In View)

라고 하지만 다들 OSIV로 부른다

 

 

▶발전 과정

  1. 과거 OSIV - 요청 당 트랜잭션

OSIV의 가장 단순한 구현 방법은 클라이언트 요청이 들어오자마자 서블릿 필터 혹은 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 것

문제점

- 컨트롤러나 뷰 같은 프리젠테이션 계층이 엔티티를 변경할 수 있다

 

고객의 정보를 제공하는 기능을 만들었고, 화면상에는 보안을 위해 고객의 이름을 "XXX"처럼 변경해서 보여주어야 한다고 가정

Member member = memberService.getMember(id);
member.setName("XXX");
model.addAttribute("member", member);​

이런 코드를 작성 할 것이다.
당연히 화면상에는 XXX로 보여지겠지만 OSIV방식을 사용하였기 때문에 member 엔티티는 영속 상태
따라서, 변경감지가 작동해 Name이 XXX로 DB에 저장된다.

해결 방법

프리젠테이션 계층에서는 엔티티를 수정하지 못하게 막는 방법

  • 엔티티를 읽기 전용 인터페이스로 제공
  • 엔티티를 읽기 전용 메서드만 가진 Wrapper 클래스로 매핑
  • DTO만 반환

이런 방법들은 코드량이 상당히 증가 한다는 단점들이 있다

따라서, 요즘에는 거의 사용하지 않는다

 

  1. 최근 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를 사용하기는 하지만 트랜잭션은 비즈니스 계층에서만 사용한다

동작 원리

  1. 클라이언트 요청이 들어오면 서블릿 필터 혹은 스프링 인터셉터에서 영속성 컨텍스트를 생성
    -> 이때 트랜잭션은 시작하지 않는다
  2. 서비스 계층에서 @Transactional로 트랜잭션을 시작할 때 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아와 트랜잭션 시작
  3. 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 플러시
    -> 영속성 컨텍스트는 유지
  4. 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지
  5. 서블릿 필터나 스프링 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료
    -> 플러시를 호출하지 않고 바로 종료

즉, 영속성 컨텍스트는 프레젠테이션 계층까지 살려두면서, 변경은 불가능하게 만든 것

 

 

정리

  • 특징
    • 클라이언트의 요청이 들어올 때 영속성 컨텍스트를 생성해서 요청이 끝날 때까지 같은 영속성 컨텍스트를 유지즉, 한 번 조회한 엔티티 요청이 끝날 때까지 영속 상태를 유지
    • 엔티티 수정은 트랜잭션이 있는 계층에서만 동작
      트랜잭션이 없는 프리젠테이션 계층은 지연 로딩을 포함해서 조회만 가능
  • 단점
    • OSIV를 사용하면같은 영속성 컨텍스트를 여러 트랜잭션이 공유할 수 있다는 점을 주의
      특히 트랜잭션 롤백시 주의
    • 프리젠테이션 계층에서 지연 로딩에 의한 SQL이 실행
      즉, 성능 튜닝시에 확인해야 할 부분이 넓어진다
    • 너무 오랜시간 동안 데이터베이스 커넥션 리소스를 사용
      따라서 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있으며, 이것은 결국 장애로 이어질 수 있다

 

  • 장점
    • 컨트롤러에서도 지연로딩이 가능
      즉, 유지보수성이 높아진다

 

 

 

참고- 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