본문 바로가기
BackEnd

JPA - 영속성 컨텍스트

by 마운틴케이 2024. 1. 15.

영속성 컨텍스트(Persistence Context)

  • JPA 내부동작의 핵심. 엔티티를 영구적으로 저장하는 환경.
  • 엔티티 매니저가 생성될 때 하나 만들어지며, 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리

엔티티의 생명 주기

  • 비영속(new/transient)
    • 단순히 엔티티 객체를 생성하여 영속성 컨텍스트에는 저장되지 않은 상태
    • em.merge() 를 통해 비영속 상태의 엔티티를 영속 상태로 만들 수 있음
  • 영속(persisted/managed)
    • 엔티티 매니저를 통해 영속성 컨텍스트에 객체를 저장하여 관리되고 있는 상태
    • EntityManager.persist(entity) ⇒ 엔티티를 영속화. 엔티티 매니저를 통해 영속성 컨텍스트에 접근해 엔티티를 관리한다.
  • 준영속(detached)
    • 영속성 컨텍스트를 통해 관리되던 엔티티가 관리하지 않게 된 상태
    • 영속성 컨텍스트가 제공하는 기능을 사용 못함(변경감지, 1차캐시 등등..)
    • 트랜잭션 커밋 시에도 아무 일도 일어나지 않음
    • 1차 캐시부터 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보가 제거됨.
      • em.detach()를 통해 직접 특정 엔티티를 준영속 상태로 만들 경우
      • em.clear() 를 통해 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만들 경우
      • em.close() 를 통해 영속성 컨텍스트를 종료할 경우
    • 준영속 상태로 만드는 방법
      • em.detach(엔티티) : 특정 엔티티만 준영속화
      • em.clear() : 영속성 컨텍스트 내의 모든 엔티티를 준영속화
      • em.close() : 영속성 컨텍스트를 종료
    • em.merge() 를 통해 준영속 상태의 엔티티를 다시 영속 상태로 만들 수 있음
  • 삭제(removed)
    • 엔티티가 영속성 컨텍스트와 데이터베이스에서 삭제된 상태

 

영속성 컨텍스트의 특징

  • 식별자가 존재
    • 영속성 컨텍스트는 엔티티를 식별자 값(@Id 로 테이블 기본키와 매핑된 값)으로 구분하기 때문에 항상 식별자가 존재
  • 플러시(Flush)
    • 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업
    • em.flush() 직접 호출 / 트랜잭션 커밋 시 플러시 자동 호출 / JPQL 쿼리, Criteria 실행 시 플러시 자동 호출
    • 플러시 실행 시 동작 과정
    1. 변경 감지 동작, 영속성 컨텍스트의 모든 엔티티를 스냅샷과 비교해 수정된 엔티티 찾음
    2. 수정된 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록
    3. 쓰기 지연 SQL 저장소의 쿼리를 데이터 베이스에 전송
  • 1차 캐시
    • 영속성 컨텍스트가 내부에 갖고있는 캐시.
    • 영속 상태의 엔티티들이 모두 이 곳에 저장
    • 키 : 엔티티의 식별자 / 값 : 엔티티 인스턴스
    • 엔티티가 영속 상태에 있을 때, 1차 캐시에 엔티티가 보관되어 엔티티 조회 시 1차 캐시에 엔티티가 존재한다면 db를 통해 조회하지 않고 바로 1차 캐시에서 반환.
    • 1차 캐시에 없을 시 db에서 조회 후 1차 캐시에 저장해 두고 다시 조회 요청이 발생했을 시 1차 캐시에서 조회
    ⇒ 성능상의 이점이 있으나 한 트랜잭션 내에서 유효한 저장 공간이기에 짧은 순간에만 존재
  • 영속 엔티티의 동일성 보장
    • 같은 식별자의 엔티티를 여러번 조회 시, 항상 1차 캐시의 같은 엔티티 인스턴스를 반환하기 때문에 같은 인스턴스로 인지
      • 동일성 : 실제 인스턴스가 같다는 것을 의미
      • 동등성 : 인스턴스가 실제 가지고 있는 값의 동일함을 의미
  • 트랜잭션을 지원하는 쓰기 지연
    • 영속 컨텍스트 내에는 쓰기 지연 SQL 저장소 라는 곳이 존재
    • 이곳에 sql을 쌓아두고 트랜잭션을 커밋할 때 한번에 DB에 보냄(flush)
  • 변경 감지(Dirty Checking)
    • 영속 상태인 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능
    • 플러시 시점에 스냅샷과 엔티티를 비교하여 변경된 엔티티를 찾고, 변경이 있을 경우 수정 쿼리를 생성, 변경사항을 데이터베이스에 반영
      • 스냅샷 : 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해 두는 것
    • 기본적으로는 변경 감지를 통해 수정 쿼리 생성 시, 엔티티의 모든 필드를 업데이트 하는 쿼리를 생성해 재사용 하도록 되어있음. → 하이버네이트의 확장 기능을 통해 동적 쿼리 생성도 가능
  • 지연 로딩(Lazy Loading)
    • 실제 객체 대신 프록시 객체를 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법
  •  

 

 

 

 

 


<<자바 ORM 표준 JPA 프로그래밍 - 김영한>> 을 보고 학습한 내용을 바탕으로 정리한 내용입니다.

 

 

댓글 피드백은 언제나 환영합니다!

'BackEnd' 카테고리의 다른 글

Nest-cli로 프로젝트 생성 시 git 추적 안되는 문제  (0) 2024.08.21
Node.js 의 이벤트 루프  (1) 2024.03.05
DDD - 엔티티와 밸류  (0) 2024.01.12
JPA 빠르게 훑어보기  (0) 2023.08.20
Spring VS SpringBoot  (0) 2020.07.23