[jpa Series] 17.cache
December 18, 2024
2차 캐시
1차, 2차
- 영속성 컨텍스트 내부에 엔티티를 보관하는 저장소가 1차 캐시
- 이 1차 캐시는 트랜잭션 시작 - 종료 시에 관여를 한다.
- 그래서 1차 캐시 자체가 엄청난 역할을 하는 건 아니다.
- JPA 구현체들은 애플리케이션 범위 캐시를 지원하는데 이를 sharedCache, secondary cache라고 한다.
- 2차 캐시를 이용하면 애플리케이션 조회 성능을 향상시킬 수 있다.
1차
- 영속성 컨텍스트 내부
- 엔티티 매니저를 통하는 길에 1차 캐싱한다.
- 끄고 켤 수 있는 것이 아니다.
- 영속성 컨텍스트 자체라고 보면 된다.
2차
- L2Cache라고 부른다.
- 분산 캐시나 클러스터링 환경의 캐시는 애플리케이션보다 더 오래 유지될 수도 있다.
- DB 조회 횟수를 실질적으로 줄일 수 있다.
- 방식은 아래와 같다.
- 영속성 컨텍스트는 엔티티가 필요하면 2차 캐시 조회
- 2차 캐시에 없으면 DB를 조회
- 결과를 2차에 올린다.
- 다음부터는 2차에서 먼저 찾고 없으면 2번을 한다.
- 반환 시에는 복사본을 만든다.
- 특징은 아래와 같다.
- 2차 캐시는 영속성 유닛 범위의 캐시다.
- 2차 캐시는 조회한 객체를 그대로 반환하는 것이 아니라 복사본을 만들어 반환
- 기본키를 기준으로 캐시하지만, 영속성 컨텍스트가 다르면 동일성 보장을 하지 않는다.
적용
- JPA 2.0에 와서 표준이 정해졌다. 그래서 세밀한 설정은 구현체 의존적이다.
@Cacheable을 사용한다.
- 캐시 모드는 아래와 같다.
- ALL : 모든 엔티티
- NONE: 캐시 사용 X
- ENABLE_SELECTIVE: Cachable(true)로 설정된 엔티티만 캐시를 적용
- DISABLE_SELECTIVE: 모든 엔티티 캐시, Cacheable(false)는 캐시 대상에서 제외
- UNSPECIFIED: JPA 구현체가 정의한 설정에 따른다.
적용
- 캐시 조회 모드, 보관 모드에 따라 사용하 프로퍼티, 옵션이 다르다.
- 프로퍼티
- jakarta.persistence.cache.retrieveMode: 캐시 조회 모드 프로퍼티 이름
- jakarta.persistence.cache.storeMode: 캐시 보관 모드 프로퍼티 이름
- 옵션
- jakarta.persistence.CacheRetrieveMode: 캐시 조회 모드 설정 옵션
- USE: 캐시에서 조회
- BYPASS: 캐시 무시
- jakarta.persistence.CacheStoreMode: 캐시 보관 모드 설정 옵션
- USE: 조회 데이터 캐시에 저장, 이미 있으면 갱신하지 않는다. 트랜잭션 커밋 시 등록/ 수정한 내용 캐시에도 저장
- BYPASS: 캐시 무시
- REFRESH: USE 전략에 추가로 DB에서 조회한 엔티티를 최신 상태로 다시 캐시
관리 API
- jakarta.persistence.Cache 인터페이스 제공
EntityManagerFactory에서 getCache() 구할 수 있다.
EhCache 적용
- 엔티티 캐시 : 엔티티 단위
- 컬렉션 캐시 : 엔티티와 연관된 컬렉션
- 쿼리 캐시 : 쿼리와 파라미터 정보를 키로 사용해서 쿼리 결과를 캐시
.setHint ("org.hibernate.cacheable", true)로 힌트 지정
사용
@Cacheable, @Cache를 붙인다.
@Cache는 CacheConcurrencyStrategy로 세부 조절한다.
- usage: CacheConcurrencyStrategy로 동시성 전략 설정
- NONE: 설정 X
- READ_ONLY: 읽기 전용. 등록, 삭제는 가능하지만 수정 불가
- NONSTRICT_READ_WRITE: 엄격하지 않은 읽고 쓰기. 동시에 같은 엔티티 수정시 일관성 깨질수 있다.
- READ_WRITE: 읽기 가능, 쓰기 가능 READ COMMITTED 정도의 격리 수준
- TRANSACTIONAL: 컨테이너 관리 환경에서 사용 REPEATABLE READ 정도
- region: 캐시 지역 설정
org.hibernate.cache.internal.StandardQueryCache: 쿼리 캐시를 저장하는 영역
org.hibernate.cahce.spi.UpdateTimestampsCache: 쿼리 캐시가 유효한지 확인하기 위해서 쿼리 대상 테이블 가장 최근 변경 시간을 저장
- include: 연관 객체를 캐시에 포함할지 선택 (all, non-lazy)