BE/Spring & Spring Boot

[Spring Boot] OSIV

baek-dev 2025. 1. 23. 19:58

OSIV (Open Session in View)란?

 

OSIV(Open Session in View)는 Hibernate와 같은 JPA 구현체에서 제공하는 디자인 패턴임.

클라이언트의 요청이 시작된 후, **영속성 컨텍스트(EntityManager)**가 View(Rendering)까지 열려 있는 상태를 유지하도록 설정함.

이 패턴은 지연 로딩(Lazy Loading)을 지원하기 위해 사용됨.


OSIV 동작 방식

1. 요청 시작

클라이언트의 요청이 들어오면, 영속성 컨텍스트가 생성됨.

 

2. 서비스 및 리포지토리 레이어 처리

서비스나 리포지토리에서 필요한 엔티티를 조회 및 수정함.

 

3. View 렌더링 단계

View에서 요청한 엔티티에 대해 지연 로딩이 필요한 경우, 영속성 컨텍스트가 열려 있으므로 추가 쿼리가 실행됨.

 

4. 응답 완료

클라이언트 응답이 끝난 후 영속성 컨텍스트가 닫힘.


OSIV 활성화와 비활성화

 

1. OSIV 활성화

 

Spring Boot에서는 OSIV가 기본적으로 활성화되어 있음.

application.properties에서 확인 가능:

spring.jpa.open-in-view=true  # 기본값

 

2. OSIV 비활성화

 

OSIV를 비활성화하면, 영속성 컨텍스트는 서비스나 리포지토리 레이어에서만 열림.

설정 방법:

spring.jpa.open-in-view=false

View에서 지연 로딩(Lazy Loading)을 사용할 수 없게 됨.


장점과 단점

 

장점

1. 지연 로딩 지원

View 렌더링 중에도 엔티티의 연관된 데이터(Lazy Loading)를 조회 가능함.

2. 코드 단순화

컨트롤러나 View에서 Lazy Loading 데이터를 사용하는 경우 추가적인 작업 없이도 동작함.

 

단점

1. 성능 문제

View 단계에서 발생하는 지연 로딩으로 인해 N+1 문제불필요한 쿼리가 발생할 가능성이 높음.

2. 영속성 컨텍스트 관리 어려움

요청이 끝날 때까지 영속성 컨텍스트가 유지되므로 메모리 관리에 영향을 줄 수 있음.

3. 트랜잭션 범위 확대 위험

영속성 컨텍스트가 오래 유지되면, 트랜잭션 관리가 복잡해질 수 있음.


OSIV 비활성화 시 대안

1. DTO 사용

View에서 필요한 데이터만 DTO로 미리 변환하여 전달함.

 

2. 페치 조인(Fetch Join)

JPA에서 JOIN FETCH를 사용해 필요한 연관 데이터를 한 번에 가져옴.

@Query("SELECT p FROM Post p JOIN FETCH p.author WHERE p.id = :id")
Post findPostWithAuthor(@Param("id") Long id);

 

3. Hibernate @BatchSize 또는 @EntityGraph 활용

연관 데이터를 효율적으로 로드하도록 설정.


OSIV가 필요한 경우와 아닌 경우

 

OSIV가 적합한 경우

간단한 프로젝트나, Lazy Loading이 View 렌더링 단계에서 자주 필요한 경우.

 

OSIV가 비적합한 경우

고성능이 요구되는 애플리케이션.

API 서버와 같이, 컨트롤러 단계에서 필요한 데이터를 전부 처리해야 하는 경우.


결론

OSIV는 편리한 지연 로딩 지원을 제공하지만, 성능 문제를 야기할 수 있음.

복잡한 서비스에서는 OSIV를 비활성화하고 DTO나 페치 조인을 활용하여 데이터를 처리하는 것이 좋음.

 


springboot에서는 기본적으로 서비스레이어와 컨트롤러레이어 에서는 함수가 끝날때까지 db커넥션이 머물러있다.

(트랜잭션처럼 더티체킹해서 저장하고 그러진않고 db만 머물러있는 상태)

서비스는 원래 springboot설정이고, 컨트롤러는 osiv설정이 켜져있을때만 적용된다.

jsp나 타임리프 할때는 유용하지만, rest api일때는 중요하지않아서 꺼도된다.

끄게된다면 컨트롤러에 @Transactional 붙이고, 읽기전용일때는 (readOnly = true) 추가.

 

OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어두는 기능입니다.

  • 영속성 컨텍스트가 트랜잭션 범위를 넘어서서도 열려있게 됩니다.
  • 기본값은 true입니다.
  • false로 설정하면 트랜잭션이 끝나는 시점에 영속성 컨텍스트를 닫습니다.
  • 이로 인해 지연로딩이 동작하지 않을 수 있습니다.
  • 이를 해결하기 위해서는 필요한 곳에 @Transactional을 붙여야 합니다.
  • 타임리프나 JSP를 사용하신 다면 켜는게 편합니다.(템플릿에서 LAZY LOADING 이 가능합니다.)
  • REST API에서는 끄는게 좋습니다.

컨트롤러의 액션메서드 수준에서 @Transactional 혹은 @Transactional(readOnly = true) 을 붙이는 이유

  1. 트랜잭션 관리의 일관성
    • 하나의 요청에서 발생하는 모든 데이터베이스 작업을 하나의 트랜잭션으로 묶을 수 있습니다.
    • 여러 개의 개별 트랜잭션이 발생하는 것을 방지합니다.
  2. 성능 최적화
    • readOnly = true 설정을 통해 읽기 전용 작업임을 명시할 수 있습니다.
    • 이를 통해 데이터베이스는 읽기 전용 트랜잭션에 대해 최적화를 수행할 수 있습니다.

 

 

 

출처 : ChatGPT