1. OSIV?

데일리·2024년 11월 1일
0

TIL

목록 보기
1/16
post-thumbnail

OSIV요?🫥 OS...7계층인가요...?

OSIV => Open Session in View
즉 뷰에서도 영속성 컨텍스트가 유지되는 것을 말한다. 이를 위해하기 위해서는 우선 영속성 컨텍스트가 뭔지 알아야된다.

1. 영속성 컨텍스트란?

영속성 컨텍스트는 JPA가 사용하는 일종의 메모리 저장소로 프로그램 내부에서 데이터베이스 일부를 임시로 저장해주는 공간이라고 볼 수 있다. 만일 데이터베이스에서 데이터를 가져오면 영속성 컨텍스트에서는 이를 캐시(임시 메모리)에 저장하고 필요할 때 데이터베이스에 접근하지 않고도 빠르게 조회할 수 있게 한다(lazy loading)

주요 기능은 아래와 같다.

  • 1차 캐시 역할
  • 변경 감지: 만일 영속성 컨텍스트에 저장된 데이터가 변경되면 트랜잭션이 끝나기 전에 변경 사항을 감지해 변경 사항을 반영
  • 동일성 보장: 조회할 때마다 데이터가 변경되지 않고 일관성을 보장한다.
  • 쓰기 지연: 수정 사항이 일어날 때마다 쿼리가 나가는 것이 아니라 트랜잭션이 끝날 때 한번에 반영

즉 쉽게 말해 캐시역할을 하는 데이터 저장소이며, 반복 조회 시 성능 향상, 데이터 변경 자동 반영 등 다양한 장점을 제공하지만, 트랜잭션이 유지되는 동안에만 관리되는 저장소라고 볼 수 있다.

2. OSIV?

OSIV는 이런 영속성 컨텍스트를 뷰단위까지 열어두는 것을 말한다. 즉 뷰에서도 엔티티(데이터)에 대한 지연로딩을 할 수 있다는 의미이다.

그게 왜 좋아...?

위와 같은 의문이 들 수도 있다. 맞다! OSIV는 대규모 트래픽이 발생하는 서비스에는 좋지 않다. 아래에서 다시 말하겠지만 뷰 단위에서 데이터 조회가 잘일어나지 않을 뿐더러 데이터 커넥션을 그 때까지 유지하는 것도 좋지 않기 때문에 주로 사용하지 않은 기술이다. 하지만 사용할 때가 가끔있는데 아래와 같다.

  • 간단한 CRUD 애플리케이션: 뷰에서 간단히 데이터 조회가 필요할 때.
  • 프로토타입 개발: 빠르게 기능을 구현하고 검증할 때 OSIV를 통해 지연 로딩을 간편히 지원할 필요가 있을 때
  • 소규모 프로젝트: 트래픽이 많지 않은 애플리케이션에서 OSIV를 활성화하여 뷰에서 데이터를 로드해야할 때

즉 MVP 모델을 만들 때나 소규모 프로젝트일 때에는 유용하게 사용할 수 있다.

3. OSIV의 동작 원리

OSIV는 간단하게 스프링 필터, 인터셉터로 구현이 가능하다.

동작원리는 아래와 같은데

  • 클라이언트의 요청이 들어오면 서블릿 필터나 스프링 인터셉터에서 영속성 컨텍스트를 생성한다.
  • 응용 계층에서 @Transactional로 트랜잭션을 시작할 때 미리 생성한 영속성 컨텍스트를 찾아와서 트랜잭션을 시작.
  • 응용 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 플러시(이 때 영속성 컨텍스트는 종료되지 않음)
  • 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지할 수 있다.
  • 필터, 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료하지만 이때 플러시는 실행되지 않는다.

4. OSIV의 장단점

OSIV의 장점은 아래와 같다.

  • 뷰 단위에서 필요할 때마다 데이터 접근이 가능하고 서비스 단위에서 복잡하게 데이터를 구분할 필요가 없다.
  • 뷰에서 지연로딩 사용 가능

위와 같은 장점이 있지만 OSIV에게 단점이 너무 많다.

  • 뷰 단위까지 데이터 커넥션이 유지되기 때문에 필요할 때 데이터 커넥션이 고갈될 수 있다.
  • 뷰 단위에서 지연로딩이 발생되기 때문에 불필요한 쿼리가 발생될 수 있다.
  • 뷰에서 데이터를 변경하면 위험성 초래

마지막 단점을 좀더 살펴보자면 만일 뷰 단위에서 데이터를 변경하면 그 시점에는 이미 트랜잭션은 종료되고 영속성 컨텍스트 내부에 있는 데이터만 변경된다.

즉 영속성 컨텍스트 메모리와 데이터베이스의 데이터가 달라지는 데이터 불일치가 발생되는 것이다.

결론적으로

대규모 애플리케이션에서는 성능 문제로 인해 OSIV를 비활성화하는 것이 일반적이며, 필요한 데이터는 DTO로 미리 변환해서 컨트롤러로 전달하는 방식이 권장을 한다. 실제 우리 회사에서도 필요한 데이터만 가공해서 DTO로 전달해준다.

Spring Boot에서는 spring.jpa.open-in-view=false 설정으로 OSIV를 끌 수 있고 만일 OSIV를 사용한다면 데이터 조회 목적으로만 사용해야 하므로, 데이터 변경 작업이 필요하다면 반드시 서비스 계층에서 트랜잭션 내에서 처리해야한다.

profile
하루에 한편 씩 읽기 좋은 테크 로그

0개의 댓글