캐시
- 기본적으로 영속성 컨텍스트를 1차 캐시라고 한다.
- 애플리케이션 범위의 2차 캐시가 있다.(공유캐시)
- 영속성 컨텍스트에 존재하지 않으면 2차 캐시를 조회한다.
- 2차캐시에도 엔티티가 없으면 데이터베이스를 조회해서 2차 캐시에 보관한다.
- 2차 캐시는 자신이 보관하고 있는 엔티티를 복사해서 반환한다.
- 2차캐시에서 얻어온 객체는 영속성 컨텍스트가 다르면 동일성(a==b)를 보장하지 않는다.
@Cacheable
@Entity
public class Member {
....
}
애플리케이션 전체에 캐시를 어떻게 적용할지 shared-cache-mode 를 설정 해줘야 한다.
(EntityManagerFactory)
SharedCacheMode 설정 종류
- ALL: 모든 엔티티를 캐시한다.
- NONE: 캐시를 사용하지 않는다.
- ENABLE_SELECTIVE: @Cacheable(true) 로 설정된 엔티티만 캐시를 적용한다.
- DISABLE_SELECTIVE: 모든 엔티티를 캐시하는데, @Cacheable(false)는 캐시하지 않는다.
- UNSPECIFIED: JPA구현체가 정의한 설정을 따른다.
캐시를 무시하고 데이터베이스를 직접 조회 하거나, 캐시를 갱신
em.setProperty("javax.persistence.cache.retrieveMode",
CacheRetrieveMode.BYPASS);
javax.persistence.cache.retrieveMode: 캐시 조회 모드 프로퍼티 이름
javax.persistence.cache.storeMode: 캐시 보관 모드 프로퍼티 이름
javax.persistence.CacheRetrieveMode: 캐시 조회 모드 설정 옵션
USE: 캐시에서 조회한다.(기본값)
BYPASS: 캐시를 무시하고 데이터베이스에 직접 접근한다.
javax.persistence.CacheStoreMode: 캐시 보관 모드 설정 옵션
USE: 조회한 데이터를 캐시에 저장한다. 이미 있는 엔티티는 조회, 갱신하지 않는다.(기본값)
BYPASS: 캐시에 저장하지 않는다.
REFRESH: USE전략에 추가로 데이터베이스에서 조회한 엔티티를 최신상태로 다시 캐시한다.
하이버네이트 ehcache를 사용하면 별도로 캐시를 얼마나 보관할지, 얼마만큼 보관할지 등을 설정할 수 있다.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>...</version>
</dependency>
- hibernate.cache.use_second_level_cache: 2차 캐시를 활성화 한다. 엔티티 캐시와 컬렉션 캐시를 사용할 수 있다.
- hibernate.cache_use_query_cache: 쿼리 캐시를 활성화 한다.
- hibernate.cache.region.factory_class: 2차 캐시를 처리할 클래스를 지정한다, EhCacheRegionFactory를 적용한다.
하이버네이트 @Cache
@Cacheable
@Entity
//하이버네이트 엔티티 레벨 캐시 설정
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Parent {
...
//하이버네이트 컬렉션 레벨 캐시 설정
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(mappedBy = "...")
private List<ChildMember> childMembers = new ArrayList<ChildMember>();
}
CacheConcurrencyStrategy 속성
- NONE: 캐시 설정 하지 않는다.
- READ_ONLY: 읽기전용 설정, 등록 삭제만 가능하다.
- NONSTRICT_READ_WRITE: 엄격하지 않은 읽고 쓰기 전략??
- READ_WRITE: 읽기, 쓰기가 가능하고 READ COMMITTED 수준의 격리수준을 보장
- TRANSACTIONAL: 컨테이너 관리 환경에서 사용할 수 있다. 설정에 따라 REPEATABLE_READ 격리수준을 보장 할 수도 있다.
각 캐시는 패키지명.클래스명 영역에 저장된다. @Cache의 region속성을 이용하면 캐시영역명을 바꿀 수 있다.
쿼리캐시
- 쿼리 캐시는 쿼리와 파라미터 정보를 키로 해서 쿼리 결과를 캐시한다.
- hibernate.cache.use_query_cache 옵션을 true로 해야한다.
- 쿼리캐시는 캐시한 시간과, 별도의 테이블이 변경됬을때 변경시간을 저장해두는 영역의 시간을 비교하여 변경된 적이 있으면 다시 캐시하도록 판단한다.
- 쿼리 캐시는 그 결과값의 식별자만을 저장하므로, 캐시된 쿼리를 다시 조회 할땐 키값에 해당하는 엔티티를 가지고 온다. 따라서 엔티티 캐시를 같이 추가하지 않으면 성능상 문제가 발생할 수 있다.
'JAVA' 카테고리의 다른 글
java annotation (0) | 2021.05.17 |
---|---|
Jackson 어노테이션 정리 (0) | 2021.04.30 |
JPA 락 처리 (0) | 2021.04.28 |
JPA 성능 최적화 (0) | 2021.04.28 |
JPA 엔티티 그래프 (0) | 2021.04.28 |