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

윤경·2021년 10월 10일
0

JPA

목록 보기
3/22
post-thumbnail

[1] 영속성 컨텍스트 1

JPA에서 가장 중요한 두 가지

  • 객체와 관계형 데이터베이스 매핑하기(Object Relational Mapping) (어떻게 매핑할건지)
  • 영속성 컨텍스트 (실제로 내부에서 어떻게 동작하느냐)

✔️ 엔티티 매니저 팩토리와 엔티티 매니저

영속성 컨텍스트란?

  • JPA를 이해하는데 가장 중요한 용어이다.

  • 굳이 번역하자면 "엔티티를 영구 저장하는 환경"이라는 뜻이다.

  • EntityManager.persist(entity);
    "엔티티 매니저에서 persist를 호출해 entity를 집어넣음"
    우리는 이렇게 객체를 저장하는구나 배웠었지만 .persist는 사실 이걸 DB에 저장한다는 것이 아니라 영속성 컨텍스트라는 곳에 저장한다는 뜻이었다.

  • 영속성 컨텍스트는 논리적인 개념이다.

  • 눈에 보이지 않으며 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

엔티티의 생명주기

엔티티에는 생명주기가 존재한다.

  • 비영속 (new/transient)
    new상태라고 하며 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태를 이른다.

  • 영속 (managed)
    영속성 컨텍스트에 관리되는 상태를 이른다.

  • 준영속 (detached)
    영속성 컨텍스트에 저장되었다가 분리된 상태를 이른다.

  • 삭제 (removed)
    삭제된 상태이다.

✔️ 비영속

before-after

✔️ 준영속, 삭제

// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태임
em.detach(member);

// 객체를 삭제한 상태
em.remove(member);

[2] 영속성 컨텍스트 2

영속성 컨텍스트의 이점

  • 1차 캐시
  • 동일성(identity) 보장
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
  • 변경 감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)

엔티티 조회, 1차 캐시

1차 캐시에서 조회

1차 캐시조회 SELECT 쿼리 없음

두 번 조회할 경우(DB에서 조회)

두 번 조회할 때

영속성 엔티티의 동일성 보장

영속 엔티티의 동일성 보장

1차 캐시로 반복 가능한 읽기 (REPEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공

엔티티 등록

트랜잭션을 지원하는 쓰기 지연
커밋하는 순간 데이터베이스에 INSERT SQL을 보냄

커밋 후 디비 저장

엔티티 수정

db먼저 확인값 업데이트변경된 값 확인

엔티티 삭제

Member memberA = em.find(Member.class, "memberA");

em.remove(memberA);	// 엔티티 삭제

[3] 플러시

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

플러시가 발생하면

(커밋되면 자동으로 플러시가 발생)

  • 변경 감지가 발생하고
  • 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록하고
  • 쓰기 지연 SQL 저장소의 쿼리(등록, 수정, 삭제쿼리)를 데이터베이스에 전송한다.

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

  • em.flush(): 직접 호출
  • 트랜잭션 커밋: 플러시 자동 호출
  • JPQL 쿼리 실행: 플러시 자동 호출

📌 왜 JPQL 쿼리 실행시 플러시가 자동 호출될까?

플러시 모드 옵션

em.setFlushMode(FlushModeType.COMMIT)
  • FlushModeType.AUTO
    가급적 기본값 사용
    커밋이나 쿼리를 실행할 때 플러시

  • FlushModeType.COMMIT
    커밋할 때만 플러시

즉,

플러시는 영속성 컨텍스트를 비우지 않는다. 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 것이 플러시이다.

트랜잭션이라는 작업 단위가 중요한 것이다. ➡️ 커밋 직전에만 동기화하면 됨.


[4] 준영속 상태

우선 영속 상태가 되는 두 가지 루트는
1. em.persist()
2. DB에서 가져와 1차 캐시에 저장
➡️ JPA가 관리하는 상태

준영속 상태란

영속 상태 → 준영속 상태가 된 것을 말한다.
영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached). 한마디로 다 빼버리는 것이다.
준영속 상태가 되면 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.

준영속 상태로 만들기

  • em.detach(entity)
    특정 엔티티만 준영속 상태로 전환

  • em.clear()
    영속성 컨텍스트를 완전히 초기화

  • em.close()
    영속성 컨텍스트를 종료


정리

강의를 다 듣고나니 이해가 되는 그림😎


profile
개발 바보 이사 중

0개의 댓글