엔티티 조회, 1차캐시
- JPA에서 1차 캐시는 엔티티를 영속성 컨텍스트에서 관리하는 캐시를 의미한다.
- find()나 getReference() 메서드로 조회한 엔티티 객체는 1차 캐시에 저장된다.
- 같은 엔티티를 다시 조회할 경우 1차 캐시에서 먼저 조회하게 되어 DB에서 조회하지 않고 캐시된 엔티티를 반환한다.
- 1차 캐시는 엔티티 매니저의 생명주기와 같이 유지된다.
- 1차 캐시에 저장된 엔티티의 상태가 변경되면 엔티티 매니저는 변경 내용을 즉시 DB에 반영하지 않아도 된다.
엔티티 저장
- 엔티티를 생성한 후 persist 메서드를 이용해 영속 상태로 만든다.
- DB PK로 지정한 값을 키로, 엔티티 자체를 값으로 1차 캐시에 저장한다.
엔티티 조회 - 1차 캐시에서 조회
- find 메서드를 사용하면 우선 DB가 아니라 1차 캐시를 조회한다.
엔티티 조회 - DB에서 조회
- 찾고자 하는 값이 1차캐시에 없으면 DB를 조회한다.
- 찾고자 하는 값이 DB에 있으면 이를 1차캐시에 저장하고 반환한다.
- 엔티티 매니저는 DB 트랜잭션 단위로 만들고, 트랜잭션 종료 시 같이 삭제된다.
- 즉, 영속성 컨텍스트와 1차캐시 역시 함께 삭제한다.
- 즉, 굉장히 짧은 시간동안(하나의 트랜잭션 안)만 영향을 끼치기 때문에 큰 이득을 가져다주진 않는다. 여러 사용자들을 위한 캐시는 아니다. (앱 전체에 공유되는 캐시는 나중에 배울 2차캐시)
1차캐시 조회 예시
- 조회를 했는데 SELECT 쿼리가 주어지지 않는다.
- 1차캐시에 저장되어있기 때문에 DB에서 가져올 필요가 없기 때문이다.
- (id = 1L인 Member 객체 저장되어있는 상태)
- 위와같은 코드를 새로 실행을 하니 조회를 하면 이번에는 SELECT 쿼리가 실행된다.
- 새로운 엔티티 매니저가 생성되어 먼저 DB에서 값을 찾아오고 1차 캐시에 저장한다. SELECT 쿼리를 실행된다.
- 두 번째 조회 시, 영속성 컨텍스트에 있는 값을 조회하기 때문에 SELECT 쿼리를 실행하지 않는다.
영속 엔티티의 동일성 보장
- 위에서 entityManager.find( … ) 는 DB에서 식별자 값이 1인 Member 엔티티를 조회하여 반환한다.
- 그리고 이를 영속성 컨텍스트에 보관한다.
- 이후 같은 식별자로 조회하면 이미 영속성 컨텍스트에 저장된 Member 엔티티를 반환하므로 세로운 쿼리를 실행하지 않는다.
- 이렇게 같은 식별자 값을 같는 엔티티는 동일한 엔티티로 인식되고, 이름 영속 엔티티의 동일성 보장이라고 한다.
- 즉, 영속 엔티티의 동일성 보장은 동일성이 아니라 식별자 값을 기준으로 한다.
- 1차 캐시로 REPEATABLE READ 등급의 트랜잭션 격리 수준을 DB가 아닌 매플리케이션 차원에서 제공한다.
- 이는 중복조회를 줄여주어 성능을 향상시키는데 도움이 된다.
트랜잭션을 지원하는 쓰기 지연
- commit을 실행할 때 쿼리가 실행됨을 알 수 있다.
- commit 하는 과정에서 INSERT SQL을 보낸다.
- 하이버네이트 옵션 중 batch_size 를 사용해 사이즈만큼 모아서 한 번에 DB에 커밋할 수 있다. (버퍼링)
- 영속성 컨텍스트 안에는 1차캐시 말고도 쓰기지연 SQL 저장소가있다.
- 1차캐시 저장과 동시에 INSERT 쿼리도 생성되어 SQL 저장소에 저장된다.
- 트랜잭션을 commit하는 순간에 쓰기지연 저장소에 있던 SQL들이 flush되어 DB에서 실행된다.
엔티티 수정 - 변경 감지
영속 엔티티를 조회해서 수정했다.
이후JPA에게 업데이트나 저장 등을 명령해야할 것 같지만,
그렇게 하지 않아도 Java Collection 처럼 처리해도 값이 적용되어있다.
- 스냅샷이란 값을 읽어온 최초 시점의 상태를 갖고있는 것을 의미한다.
- commit이 일어나면, 1차캐시의 엔티티와 스냅샷의 비교가 일어난다.
- commit을 명령하면 내부 flush()가 일어난다.
- JPA가 엔티티와 스냅샷을 전부 비교한다.
- 변경된 사항이 있을 경우 UPDATE 쿼리를 쓰기지연 SQL 저장소에 저장한다.
- DB에 반영하고 commit한다.
엔티티 삭제
'[Spring] > JPA 프로그래밍 - 기본편' 카테고리의 다른 글
준영속 상태 (0) | 2023.04.10 |
---|---|
플러시 (0) | 2023.04.09 |
영속성 컨텍스트 1 (0) | 2023.04.07 |
Hello JPA - 애플리케이션 개발 (0) | 2023.03.28 |
Hello JPA - 프로젝트 생성 (0) | 2023.03.27 |