영속성 컨텍스트의 CRUD

신상현·2021년 2월 2일
0

Spring Boot와 JPA

목록 보기
5/16

식별자 값

  • 식별자 값은 DB의 기본 키 값과 매핑되어 있다.
  • 영속성 컨텍스트는 Entity를 식별자 값으로 구분한다.
  • 따라서 영속 상태의 Entity는 식별자 값이 무조건 있어야 한다.
  • 또한, 영속성 컨텍스트에 데이터를 저장, 조회하는 모든 기준은 DB의 기본 키이다.

영속성 컨텍스트와 DB 저장

  • JPA는 트랜젝션을 커밋하는 순간, 영속성 컨텍스트의 entity를 DB에 반영한다.

영속성 컨텍스트의 CRUD


1차 캐시

  • 영속성 컨텍스트 내부에 캐시를 갖고 있다.
  • 영속 상태의 Entity는 모두 1차 캐시에 저장된다.
  • key를 식별자 값으로 하고, value를 Entity 객체로 한다.

em.find(Member.class, "member1") 으로 조회

  • 1차 캐시에 member1의 식별자 값을 갖는 데이터가 존재할 때
    • 1차 캐시에서 엔티티 객체를 조회한다.

  • 1차 캐시에 member1의 식별자 값을 갖는 데이터가 존재하지 않으면
    • DB에서 member1의 기본 키 값을 갖는 데이터를 조회한다.
    • 조회한 데이터로 엔티티 객체를 만든다.
    • 1차 캐시에 엔티티 객체를 영속시킨다.
    • 영속성 컨텍스트에 영속된 엔티티 객체를 반환한다.

동일성 보장

  • 영속성 컨텍스트는 1차 캐시에 있는 값을 반환한다.
  • 연속 2번의 조회 시, 반환된 엔티티 객체는 동일한 엔티티 인스턴스이다.
  • 따라서, 엔티티의 동일성을 보장한다.

쓰기 지연

tx = em.getTransaction();
tx.begin()
// Entity Manager는 데이터 변경 시 트랜젝션을 시작해야한다.

em.persist(A);
em.persist(B);
// 여기까지 Insert SQL을 보내지 않는다.

// 트랜젝션을 커밋하는 순간 DB에 Insert SQL을 날린다.
tx.commit();
  1. persist()로 엔티티 객체를 영속시키면 1차 캐시에 저장한다.
  2. SQL 쿼리를 만들어서 내부의 쓰기 지연 쿼리 저장소에 Insert SQL을 모아둔다.
  3. 트랜젝션의 commit()이 실행되면, 쿼리 저장소의 쿼리들을 flush 한다.
  4. 쿼리들을 실행해서, 영속성 컨텍스트와 DB를 동기화한다.(= 같게만든다.)
  5. 실제 DB에서 트랜젝션 커밋이 완료된다.

JPA가 생성한 쿼리들을 DB에서 커밋하기 전에만 보내면 된다.
따라서, 한 번에 쿼리들을 전달함으로써 성능 최적화가 가능하다.

변경 감지

SQL을 직접 수정하는 경우

  • 수정 사항이 발생하는 SQL을 직접 수정해줘야 한다.
  • 결국, SQL에 의존적인 개발이 된다.

변경 감지를 사용하는 경우

  • 최조 엔티티 객체가 영속될 때의 상태를 복사, 저장해둔다.(=스냅샷)
  • flush가 일어날 때, 현재 상태와 스냅샷을 비교한다.
  • 수정 사항을 SQL로 만들어서 쿼리 저장소에 보낸다.
  • 쿼리들이 DB에 반영되고, 트랜젝션이 DB에서 커밋된다.

변경 감지 전략

  • 변경 감지는 영속 상태의 엔티티 객체에만 적용된다.
  • update 쿼리는 모든 필드를 다룬다. 데이터 전송량이 증가하긴 하지만,
    1. 모든 필드를 다루면, 항상 update 쿼리가 항상 같아 재사용성이 증가한다.
    2. DB에 동일한 쿼리를 날리면, DB에서도 캐싱을 이용하여 재사용성이 증가한다.
  • 수정된 필드에 대해서만 다루는 것도 어노테이션을 통해서 가능하다. @DynamicUpdate

엔티티 삭제

Memebr A = em.find(Member.class, "1");
em.remove(A)
  • remove가 실행되면, Delete 쿼리가 쿼리 저장소에 등록된다.
  • 엔티티 객체 A는 영속성 컨텍스트에서 제거된다.
profile
개발자 싱상형

1개의 댓글

comment-user-thumbnail
2021년 10월 1일

우연히 들어왔는데 신상이넹ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
공부하고 갑니당 ㅎㅎ

답글 달기

관련 채용 정보