JPA

[JPA] 1차 캐시

개발 공주 2023. 7. 9. 15:25
728x90

📌 영속성 컨텍스트는 Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간입니다.

  • 영속성 컨텍스트가 어떻게 Entity 객체를 효율적으로 관리하고 있는지 살펴보겠습니다.

1차 캐시

  • 영속성 컨텍스트는 내부적으로 캐시 저장소를 가지고 있습니다.
    • 우리가 저장하는 Entity 객체들이 1차 캐시 즉, 캐시 저장소에 저장된다고 생각하시면됩니다.
    • 캐시 저장소는 Map 자료구조 형태로 되어있습니다.
      • key에는 @Id로 매핑한 기본 키 즉, 식별자 값을 저장합니다.
      • value에는 해당 Entity 클래스의 객체를 저장합니다.
      • 영속성 컨텍스트는 캐시 저장소 Key에 저장한 식별자값을 사용하여 Entity 객체를 구분하고 관리합니다.

1차 캐시 장점

  1. DB 조회 횟수를 줄임
  2. '1차 캐시'를 사용해 DB row 1개 당 객체 1개가 사용되는 것을 보장 (객체 동일성 보장)
    • 객체 동일성 보장
@Test
@DisplayName("객체 동일성 보장")
void test4() {
    EntityTransaction et = em.getTransaction();

    et.begin();
    
    try {
        Memo memo3 = new Memo();
        memo3.setId(2L);
        memo3.setUsername("Robbert");
        memo3.setContents("객체 동일성 보장");
        em.persist(memo3);

        Memo memo1 = em.find(Memo.class, 1);
        Memo memo2 = em.find(Memo.class, 1);
        Memo memo  = em.find(Memo.class, 2);

        System.out.println(memo1 == memo2);
        System.out.println(memo1 == memo);

        et.commit();
    } catch (Exception ex) {
        ex.printStackTrace();
        et.rollback();
    } finally {
        em.close();
    }

    emf.close();
}
  • 같은 값을 조회하는 memo1과 memo2는 == 결과 true를 반환합니다.
  • memo1과 다른 값을 조회하는 memo는 == 결과 false를 반환합니다.

저장

em.persist(memo); 메서드가 호출되면 memo Entity 객체를 캐시 저장소에 저장합니다.

@Test
@DisplayName("1차 캐시 : Entity 저장")
void test1() {
    EntityTransaction et = em.getTransaction();

    et.begin();

    try {

        Memo memo = new Memo();
        memo.setId(1L);
        memo.setUsername("Robbie");
        memo.setContents("1차 캐시 Entity 저장");

        em.persist(memo);

        et.commit();

    } catch (Exception ex) {
        ex.printStackTrace();
        et.rollback();
    } finally {
        em.close();
    }

    emf.close();
}

조회

  1. 캐시 저장소에 조회하는 Id가 존재하지 않은 경우
      1. 캐시 저장소 조회
      2. DB SELECT 조회 후 캐시 저장소에 저장

  • em.find(Memo.class, 1); 호출 시 캐시 저장소를 확인 한 후 해당 값이 없다면?
  • DB에 SELECT 조회 후 해당 값을 캐시 저장소에 저장하고 반환합니다.
  • DB에서 데이터를 조회만 하는 경우에는 데이터의 변경이 발생하는 것이 아니기 때문에 트랜잭션이 없어도 조회가 가능합니다.
  • Memo memo = em.find(Memo.class, 1); 호출 시 캐시 저장소에 해당 값이 존재하지 않기 때문에 DB에 SELECT 조회하여 캐시 저장소에 저장한 후 반환합니다.

 

2.캐시 저장소에 조회하는 Id가 존재하는 경우

  • em.find(Memo.class, 1); 호출 시 캐시 저장소에 식별자 값이 1이면서 Memo Entity 타입인 값이 있는지 조회합니다.
    • 값이 있다면 해당 Entity 객체를 반환합니다.


삭제

1.삭제할 Entity를 조회한 후 캐시 저장소에 없다면 DB에 조회해서 저장합니다.

 

2. em.remove(entity);

em.remove(memo); 호출 시 삭제할 Entity를 DELETED 상태로 만든 후 트랜잭션 commit 후 Delete SQL이 DB에 요청됩니다.

'JPA' 카테고리의 다른 글

[JPA] 변경감지 (Dirty Checking)  (1) 2023.07.09
[JPA] 쓰기 지연 저장소  (0) 2023.07.09
[JPA] 트랜잭션  (0) 2023.07.09
[JPA] 영속성 컨텍스트  (0) 2023.07.09
[JPA] Entity  (0) 2023.07.09