컴퓨터 프로그래밍/Spring

[Spring] 영속성 컨텍스트의 기능

한33 2024. 8. 21. 21:57

 

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

1차 캐시

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

Entity 저장

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


Entity 조회

  • em.find(Memo.class, 1); 호출 시 캐시 저장소를 확인 한 후 해당 값이 없다면?
  • DB에 SELECT 조회 후 해당 값을 캐시 저장소에 저장하고 반환

  • em.find(Memo.class, 1); 호출 시 캐시 저장소에 식별자 값이 1이면서 Memo Entity 타입인 값이 있는지 조회.
    • 값이 있다면 해당 Entity 객체를 반환
  • '1차 캐시' 사용의 장점
    1. DB 조회 횟수를 줄임
    2. *1차 캐시*를 사용해 DB row 1개 당 객체 1개가 사용되는 것을 보장 (객체 동일성 보장)

Entity 삭제


쓰기 지연 저장소 (ActionQueue)

 

JPA는 이를 구현하기 위해 쓰기 지연 저장소를 만들어 SQL을 모아두고 있다가 트랜잭션 commit 후 한번에 DB에 반영

 

flush()

flush 를 호출하면, Hibernate 는 변경된 Entity 의 상태를 기반으로 SQL 쿼리를 작성하고 이를 데이터베이스로 전송, 이 때 SQL 로그에 쿼리가 기록됨.

그러나 이 쿼리는 아직 트랜잭션이 commit 되지 않았기 때문에 실제로 데이터베이스에 반영되지 않음.

 

최종적으로 commit 후에 flush 처리 되지 않은 SQL 쿼리들을 한 번에 작성하게 됨


변경 감지 (Dirty Checking)

  • 영속성 컨텍스트에 저장된 Entity가 변경될 때마다 Update SQL이 쓰기 지연 저장소에 저장된다면?
    • 하나의 Update SQL로 처리할 수 있는 상황을 여러번 Update SQL을 요청하게 되기 때문에 비효율적

  • JPA는 영속성 컨텍스트에 Entity를 저장할 때 최초 상태(LoadedState)를 저장
    • 트랜잭션이 commit되고 em.flush(); 가 호출되면 Entity의 현재 상태와 저장한 최초 상태를 비교
    • 변경 내용이 있다면 Update SQL을 생성하여 쓰기 지연 저장소에 저장하고 모든 쓰기지연 저장소의 SQL을 DB에 요청
    • 마지막으로 DB의 트랜잭션이 commit 되면서 반영
  • 따라서 변경하고 싶은 데이터가 있다면 먼저 데이터를 조회하고 해당 Entity 객체의 데이터를 변경하면 자동으로 Update SQL이 생성되고 DB에 반영
    • 이러한 과정을 변경 감지, Dirty Checking이라 부름
  •