[JPA] Context 주기와 트랜잭션 주기 그리고 OSIV

2024. 5. 8. 06:51·백엔드/JPA
목차
  1. 스프링의 @Transactional 어노테이션과 트랜잭션 범위
  2. 만약 준영속 상태에서 지연로딩 문제를 해결하기 위해선?
  3. 문제점
  4. 해결방법
  5. 글로벌 패치 전략
  6. JPQL 페치 조인
  7. 강제로 초기화
  8. FACADE 계층 추가
  9. OSIV (Open Session In View)
  10. 과거 OSIV: 요청 당 트랜잭션
  11. 스프링 OSIV: 비즈니스 계층 트랜잭션

스프링의 @Transactional 어노테이션과 트랜잭션 범위

  • 스프링의 Service 계층에 @Transactional 어노테이션을 많이 봤을 것이다.
  • 스프링의 @Transactional 어노테이션은 AOP로 구현되었으며, 메소드 시작할때 영속성 컨텍스트와 트랜잭션을 시작한다.
  • 대상 메소드가 종료하면 트랜잭션을 커밋하고 종료한다.
  • 트랜잭션을 종료하면 영속성 컨텍스트도 종료하고 같은 트랜잭션에는 같은 영속성 컨텍스트를 사용한다.
  • 트랜잭션을 커밋하면 컨텍스트를 플러시하고 변경 내용을 데배에 반영한다.
    • 그리고 데이터베이스의 트랜잭션을 커밋한다.
    • 따라서 영속성 컨텍스트의 변경 내용이 데이터베이스에 정상 반영된다.
    • 만약 트랜잭션의 예외가 발생하면 트랜잭션을 종료하는데 이때는 플러시를 하지 않는다.
요약

스프링의 트랜잭션 어노테이션은 -> AOP로 구현됨
트랜잭션의 주기와 영속성 컨텍스트의 생존 주기가 같음
같은 트랜잭션이면 같은 영속성 컨텍스트의 접근함

만약 준영속 상태에서 지연로딩 문제를 해결하기 위해선?

문제점

  • 준영속 상태의 엔티티를 지연로딩으로 연관 엔티티를 조회하거나
  • 변경을 하게 된다면 감지를 못해서 에러가 나거나 원하는 결과를 가질 수 없다.

해결방법

  • 영속성 컨텍스트가 종료되기 전에 즉시 로딩
    • 글로벌 패치 전략 수정(지연 → 즉시)
    • JPQL 페치 조인
    • 강제로 초기화
    • FACADE 계층 추가
  • OSIV를 사용하여 엔티티를 항상 영속 상태로 유지

글로벌 패치 전략

  • 지연로딩을 → 즉시로딩으로 수정함으로써 엔티티를 로딩할 때 바로 로딩되게끔
  • 문제점
    • 유연하지 못한 로딩 전략
      • 다른 코드에서는 연관 엔티티를 사용안 할수도 있음
    • N+1 문제

JPQL 페치 조인

  • 가장 많이 쓰는거 같음
  • 한번의 쿼리로 연관된 엔티티 한번의 조회
  • JPQL 페치 조인으로 N+1 문제 해결
  • 문제점
    • 엔티티 종류마다 메소드를 만들어서 repository 의존도가 상승할 수 있음

강제로 초기화

  • 지연로딩인 엔티티를 강제로 초기화 하여 로딩되게 함
  • 문제점
    • 글로벌 패치 전략과 동일
    • 코드가 지저분해질 수도?

FACADE 계층 추가

  • 위에 강제로 초기화 처럼 엔티티를 초기화하는 코드를 사용하다보면 Service 계층의 역할이 SRP 이 잘 구현하기 힘들다
  • 그래서 엔티티를 초기화하는 Facade 계층을 추가하는 방법이 있다.
  • 하지만 이는 코드의 역할 분리에는 좋지만 코드가 증가하고 계층에 분리로 인한 가독성이 떨어질 수 있다.

OSIV (Open Session In View)

  • JPA에서는 OEIV 라고 부르기도 한다(OSIV는 하이버네이트에서 부른다)
  • OSIV의 목적은 영속성 컨텍스트를 프레젠테이션 계층까지 열어두는 것이다.
    • 즉, Service → Repository 계층에만 국한되어 있지않게 끔 하는 것

과거 OSIV: 요청 당 트랜잭션

  • 과거 OSIV 는 요청당 스레드를 할당하면서 영속성 컨텍스트와 트랜잭션를 생성했다.
  • 따라서 Transaction per Request라고 부르기도 한다.
  • 문제점
    • 프레젠테이션 계층에서 엔티티 변경 위험
      • 엔티티 변경을 위한 해결방안
        • 엔티티를 읽기 전용 인터페이스로 제공
        • 엔티티 레핑
        • DTO만 반환
      • 하지만 위와 같은 해결방안은 해결방안이지만 해결하기 위한 부수적인 요소가 많아 사실상 과거 OSIV 는 안좋은 요소가 많다.

스프링 OSIV: 비즈니스 계층 트랜잭션

  • 사용자의 요청에 영속성 컨텍스트를 생성한다.
  • 그리고 트랜잭션을 생성 ~ 종료 와 영속성 컨텍스트의 생존과는 무관하다.
  • 요청이 끝날 때 영속성 컨텍스트를 종료한다.
  • 특징
    • 영속성 컨텍스트를 프리젠테이션 계층까지 유지한다.
    • 프리젠테이션 계층에는 트랜잭션이 없으므로 엔티티를 수정할 수 없다.
    • 프리젠테이션 계층에는 트랜잭션 없이 읽기를 사용해서 지연 로딩을 할 수 있다.

트랜잭션 없이 읽기

  • 영속성 컨텍스트의 주기는 요청의 주기와 같은데, 이 때 지연로딩이 트랜잭션 없이도 가능하다.
  • 업데이트나 저장 같은 쿼리는 트랜잭션이 필요하다 하지만, 읽기 같은 조회는 트랜잭션 없이도 가능하기 때문에 가능하다!

주의 사항

  • OSIV를 사용하면 영속성 컨텍스트는 요청의 주기와 같다
  • 그렇다는 건 DataSource를 요청이 처리할 동안 쓰기 때문에 요청이 많은 서비스이면 장애가 발생하기 쉽다.
  • DB 접근을 안하는 요청에도 자원을 쓸것 같아서 흠… 쓰기 애매한거 같다.

사용법

spring.jpa.open-in-view:true #디폴트 세팅

사용하지 않을 때는 false로 해두어야 한다.

 

 

 

참고자료

- >자바 ORM 표준 JPA 프로그래밍 - 김영한

'백엔드 > JPA' 카테고리의 다른 글

SpringDataJpa 알고 사용하시나요? - 공식 문서 훑어보기  (0) 2025.08.24
[JPA] JPA N+1 문제 발생 원인과 해결 방법  (0) 2024.05.14
[JPA] 엔티티 그래프  (0) 2024.05.10
  1. 스프링의 @Transactional 어노테이션과 트랜잭션 범위
  2. 만약 준영속 상태에서 지연로딩 문제를 해결하기 위해선?
  3. 문제점
  4. 해결방법
  5. 글로벌 패치 전략
  6. JPQL 페치 조인
  7. 강제로 초기화
  8. FACADE 계층 추가
  9. OSIV (Open Session In View)
  10. 과거 OSIV: 요청 당 트랜잭션
  11. 스프링 OSIV: 비즈니스 계층 트랜잭션
'백엔드/JPA' 카테고리의 다른 글
  • SpringDataJpa 알고 사용하시나요? - 공식 문서 훑어보기
  • [JPA] JPA N+1 문제 발생 원인과 해결 방법
  • [JPA] 엔티티 그래프
천방지축 개발자
천방지축 개발자
기록용 블로그
    250x250
  • 천방지축 개발자
    KKanging
    천방지축 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (121)
      • 백엔드 (31)
        • Spring framework (4)
        • SpringSecurity (6)
        • JPA (4)
        • DB (6)
        • Spring Cloud (2)
        • CI CD (0)
        • 아키텍처 & 패러다임 & 디자인 패턴 (5)
        • 시스템 설계 & 성능 개선 (4)
      • JAVA (5)
        • 언어 (3)
        • JVM (4)
      • cs (57)
        • 운영체제 (8)
        • 컴퓨터네트워크 (6)
        • 자료구조 (15)
        • 알고리즘 (8)
        • http (20)
      • 인공지능 (5)
        • Reinforcement Learning (5)
      • 기타 (9)
        • 백준 (2)
        • python (2)
        • 백준 장학금 (5)
      • 회고 (5)
        • 토덕-리팩터링 (2)
      • 아티클 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    힙트리
    jpa n+1 문제
    MSA
    스케줄링
    점근적 표기법
    멀티프로세서
    백준 장학금
    최소힙
    Kruskal
    연결리스트 종류
    JVM
    운영체제
    프로세스
    posix
    AVL트리
    자료구조
    엔티티 그래프
    heapq
    python
    HTTP
    알고리즘
    최대 힙
    이분탐색이란
    백준장학금
    JPA
    강화학습
    SpringSecurity
    spring
    연결리스트
    완전이진트리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
천방지축 개발자
[JPA] Context 주기와 트랜잭션 주기 그리고 OSIV

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.