[JPA] 영속성 관리: 내부 동작 방식

Jiisuniui·2023년 12월 1일
1

JPA의 모든 것

목록 보기
2/8
post-thumbnail

JPA에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑하기
  • 영속성 컨텍스트

영속성 컨텍스트

엔티티 매니저 팩토리가 -> 엔티티 매니저를 만든다

1. 영속성 컨텍스트란?

  • Entity를 영구 저장하는 환경
  • EntityManager.persist(entity): entity를 영속성 컨텍스트에 저장해서 영속성화한다.
    -> entity manager를 통해서 영속 컨텍스트에 접근하는 방식

2. 엔티티의 생명주기

  • 비영속 (new/transient): 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속 (managed): 영속성 컨텍스트에 관리되는 상태
  • 준영속 (detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제 (remove): 삭제된 상태

3. 영속성 컨텍스트의 이점

  • 1차 캐시

    • 하나의 transaction 안에서만 동작하기 때문에 엄청 큰 이득은 아니다
      image
  • 동일성 보장(identity)

    • 1차 캐시로 반복가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 어플리케이션 차원에서 제공
    • 1차 캐시에 저장된걸 객체마냥 비교할 수 있다 (==)
  • 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

    • 쓰기지연 SQL 저장소가 있는데 거기 저장해뒀다가 하나의 트랜잭션이 끝나면 실제로 db로 날라감
  • 변경 감지 (Dirty Checking)

    • 1차 캐시와 비교해서 변경이 감지되면 쓰기지연SQL에 넣어둠
      image
  • 지연 로딩 (Lazy Loading)

플러시

영속성 컨텍스트의 변경내용을 데이터베이스에 반영

1. 플러시 발생

  • 변경감지
  • 수정된 엔티티 쓰기지연 SQL저장소에 등록
  • 쓰기지연 SQL저장소의 쿼리를 db에 전송 (등록,수정,삭제)

2. 영속성 컨텍스트를 플러시 하는 방법

  • em.flush() : 직접호출 -> 1차캐시는 남아있음(영속성컨텍스트 비우지 않음), sql들 db에 반영만
  • 트랜잭션 커밋 : 자동호출
  • JPQL 쿼리 실행 : 자동호출 -> 중간에 실행시키면 문제가 될 수 있어서, 방지하고자 flush 날리고 쿼리 실행

3. 플러시모드 옵션

  • FlushModeType.Auto : 커밋이나 쿼리를 실행할 때 플러시 (기본값,권장값)
  • FlushModeType.COMMIT : 커밋할 때만 플러시

4. 플러시는

  • 영속성 컨텍스트를 비우지 않음
  • 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
  • 트랜잭션 작업 단위가 중요 -> 커밋 직전에만 동기화하면 됨 (flush->commit)

준영속 상태

1. 준영속 상태란

  • 영속 -> 준영속
  • 영속상태의 entity가 영속성 컨텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

2. 준영속상태로 만드는 방법

  • em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
  • em.clear() : 영속성 컨텍스트 완전히 초기화
  • em.close() : 영속성 컨텍스트를 종료

참고

profile
why error?

0개의 댓글