[3장] 영속성 관리

1. 엔티티 매니저 팩토리와 엔티티 매니저

엔티티 매니저 팩토리

  • 리소스 사용 ↑
  • 여러 스레드 동시 접근해도 안전해서 스레드 간 공유에 이슈 없음
  • Hibernate 포함 JPA 구현체 → 팩토리 생성 시 DB 커넥션 풀 생성

엔티티 매니저

  • 리소스 사용 거의 X
  • 여러 스레드 동시 접근시 동시성 이슈 발생 → 공유하면 안됨
  • 데이터베이스 연결이 필요한 시점까지 DB 커넥션 사용 X
    • 보통 트랜잭션을 시작할 때, DB 커넥션 획득

 

2. 영속성 컨텍스트란?

영속성 컨텍스트( JPA 이해에 제일 중요한 용어 )

  • 엔티티를 영구 저장하는 환경
  • 엔티티 저장/조회시, 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리
  • 엔티티 매니저가 생성될 때, 같이 생성

 

3. 엔티티의 생명주기

엔티티의 4가지 상태

  • 비영속: 영속성 컨텍스트와 전혀 관계가 없는 상태
    • 엔티티 객체를 생성하였지만, 저장하지 않아 DB나 영속성 컨텍스트와 전혀 관련 없는 상태
    • persist() 메소드 호출 이전 상태
  • 영속: 영속성 컨텍스트에 저장된 상태
    • 엔티티 매니저를 통해 엔티티를 영속성 컨텍스트에 저장한 상태
    • 영속성 컨텍스트가 관리하는 엔티티
    • find() 메소드로 조회한 엔티티 상태
  • 준영속: 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 영속성 컨텍스트가 관리하던 영속 상태 엔티티를 관리하지 않는 상태
    • detach, close, clear 메소드 호출 시 준영속 상태가 됨
  • 삭제

 

4.영속성 컨텍스트의 특징

  • 영속성 컨텍스트의 식별자 값
    • 영속 상태는 식별자 값이 반드시 필요
    • 영속성 컨텍스트가 식별자 값으로 엔티티 구분
  • 영속성 컨텍스트와 DB 저장
    • 트랜잭션이 커밋되는 순간 영속성 컨텍스트에서 DB에 반영(FLUSH)
  • 영속성 컨텍스트 → 엔티티 관리시 장점
    • 1차 캐시
    • 동일성 보장
    • 트랜잭션 지원 쓰기 지연
    • 변경 감지
    • 지연 로딩

 

4-1. 엔티티 조회

  • 영속성 컨텍스트 내부에 1차 캐시 존재(영속 상태 엔티티 저장용)
  • 1차 캐시의 key값은 식별자(id) 값(DB 기본 키와 매핑)
    • 영속성 컨텍스트에 데이터를 저장하고 조회하는 기준 = DB 기본 키 값

 

1차 캐시에서 조회: 1차 캐시에서 식별자 값으로 조회 → 있다면 메모리에서 엔티티 조회

DB에서 조회: 엔티티가 1차 캐시에 없다면 DB에서 조회후 엔티티 생성 → 1차 캐시에 저장

영속 엔티티 동일성 보장: 1차 캐시에 저장된 엔티티 값은 동일

 

4-2. 엔티티 등록

  • 트랜잭션 커밋시 엔티티 매니저는 우선적으로 영속성 컨텍스트 FLUSH
  • FLUSH: 영속성 컨텍스트 변경 내용을 DB에 동기화(CUD 작업 한번에 반영)
  • 쓰기 지연 SQL 저장소에 모인 쿼리를 DB에 전송 후 변경 내용을 DB에 동기화 → DB 트랜잭션 커밋

 

4-3. 엔티티 수정

SQL 수정 쿼리 문제점

  • 비즈니스 로직 분석에 SQL 확인이 필수
  • 직/간접적으로 비즈니스 로직이 SQL에 의존하게됨

 

4-4. 엔티티 삭제

  • 엔티티 삭제시 삭제 대상 엔티티 조회 필요
    • remove 메소드에 삭제 대상 넘겨주면 엔티티 삭제
      • remove 메소드 호출 즉시 영속성 컨텍스트에서 삭제 대상 제거 → 재사용 X
    • 즉시 삭제가 아닌, 삭제 쿼리를 쓰기지연 SQL 저장소에 등록

 

5. 플러시

  • 영속성 컨텍스트의 변경 내용을 DB에 반영
    • 변경 감지로 영속성 컨텍스트의 모든 엔티티를 스냅샷과 비교하여 수정된 엔티티 조회
    • 수정된 엔티티가 있다면 수정쿼리를 생성하여 쓰기 지연 SQL 저장소에 등록
    • 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송
  • 영속석 컨텍스트 플러시 방법
    • flush 메소드 직접 호출
      • 영속성 컨텍스트를 강제로 플러시 → 테스트 or 다른 프레임워크 제외하면 거의 사용 X
    • 트랜잭션 커밋시 자동 호출
    • JPQL 쿼리 실행시 자동 호출
      • 쿼리 실행 직전 플러시로 변경 내용 DB 최신화
      • find 메소드 호출시에는 플러시 실행 X

 

5-1. 플러시 모드 옵션

AUTO: 커밋이나 쿼리 실행시 플러시

COMMIT: 커밋할 때만 플러시

  • 플러시 모드 별도 설정 X → AUTO 옵션으로 동작
  • COMMIT 옵션: 성능 최적화 용도 사용

플러시: 영속성 컨텍스트 변경 내용을 DB에 동기화하는 작업

 

6. 준영속

준영속 상태에서는 영속성 컨텍스트가 제공하는 기능 사용 X

영속 상태를 준영속 상태로 변경하는 메소드

  • detach(entity): 특정 엔티티를 준영속 상태로 전환
    • 메소드 호출 즉시 1차 캐시 부터 쓰기 지연 SQL 저장소까지 해당 엔티티 모든 관리 정보 제거
  • clear(): 영속성 컨텍스트 완전 초기화
    • 변경 감지 동작 X
  • close(): 영속성 컨텍스트를 종료

 

6-1. 준영속 상태의 특징

  • 거의 비영속 상태에 가까움
    • 영속성 컨텍스트 제공 기능 동작 X
  • 식별자 값을 가지고 있음
    • 한번 영속 상태였으므로 식별자 값이 있음
  • 지연 로딩을 할 수 없음
    • 실제 객체 대신 프록시 객체 로딩 후 실제 사용시 영속성 컨텍스트에서 조회하는 방식의 지연 로딩시 영속성 컨텍스트 문제 발생

 

6-2. 병합: merge()

  • 준영속 상태의 엔티티를 다시 영속 상태로 변경시 사용
  • 준영속 상태의 엔티티 정보로 새로운 영속 상태의 엔티티 반환
    • 기존의 엔티티는 그대로 준영속 상태 / merge 메소드로 반환된 엔티티가 영속 상태 → 서로 다른 인스턴스
    • 준영속 엔티티 참조 변수가 영속 엔티티 참조하게 변경하는게 안전
  • 비영속 상태의 엔티티도 영속으로 변경 가능
    • 영속성 컨텍스트/DB 조회 후 없을 시 신규 엔티티 생성
  • save or update 기능 수행

'책 스터디 정리 > JPA ORM 스터디' 카테고리의 다른 글

[7장] 고급 매핑  (0) 2023.05.09
[6장] 다양한 연관관계 매핑  (0) 2023.05.02
[5장] 연관관계 매핑 기초  (0) 2023.04.25
[4장] 엔티티 매핑  (0) 2023.04.18
[1장] JPA 소개  (0) 2023.04.04