컴퓨터 프로그래밍/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차 캐시' 사용의 장점
- DB 조회 횟수를 줄임
- *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이라 부름