동시성 전략
Hibernate에서 2차 캐싱을 활성화한 후에는 Hibernate에 어떤 Entity 개체를 어떻게 캐싱할지 설명해야 합니다.
이를 위해 Hibernate는 Entity 클래스에 대한 특별한 주석 - @Cache를 가지고 있습니다 . 예:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
이 주석은 두 번째 수준 캐시를 사용하려는 각 엔터티 엔터티에 대해 작성해야 합니다. 예:
@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
@Id
private Integer id;
private Set<Task> tasks;
}
Hibernate는 캐시된 엔터티가 다른 스레드에서 액세스되는 경우 4가지 가능한 액세스 전략을 가지고 있습니다.
- 읽기 전용
- 읽기-쓰기
- 엄격하지 않은 읽기-쓰기
- 트랜잭션
읽기 전용. 절대 변경되지 않는 데이터에 적합한 동시성 전략. Hibernate는 단순히 이러한 객체를 메모리에 저장합니다. 참조 데이터로만 사용하십시오.
데이터베이스는 절대 변경되지 않는 많은 정보를 저장합니다. 예를 들어 테이블은 추가되기만 하고 변경되거나 제거되지는 않는 이벤트 목록을 유지합니다. Hibernate를 통해 이 테이블로 작업해야 하는 경우 읽기 전용 캐싱 전략이 적합합니다.
읽기-쓰기 (읽기-쓰기). 주로 읽을 수 있는 데이터에 이 전략을 사용하십시오. 그러나 Hibernate는 이 데이터를 변경하려는 시도를 추적할 것이지만 이러한 시도가 매우 드물 것으로 예상합니다.
거의 변경되지 않고 자주 읽거나 요청되는 객체를 주로 캐시해야 합니다. 이러한 개체가 있는 경우 해당 개체에 대한 읽기-쓰기 전략을 사용해야 합니다.
비엄격-읽기-쓰기 . 이 전략은 캐시와 데이터베이스 간의 일관성을 보장하지 않습니다. 데이터가 거의 변경되지 않고 오래된 데이터의 작은 가능성이 중요한 문제가 아닌 경우 이 전략을 사용합니다.
읽기-쓰기 전략과 달리 이 전략은 변경 가능한 데이터가 읽기용으로 잠겨 있지 않다고 가정합니다. 이로 인해 개체가 한 곳에서 변경되는 동안 다른 곳에서는 누군가가 이전 버전을 읽고 있을 수 있습니다.
예를 들어 사용자가 자신의 댓글을 변경했지만 다른 사용자는 얼마 동안 자신의 이전 버전을 계속 볼 수 있습니다. 이것이 문제가 되지 않는다면 nonstrict-read-write 전략을 사용하십시오.
트랜잭션 . 드물게 업데이트되는 동시 트랜잭션에서 부실 데이터를 방지하는 것이 중요한 읽기 전용 데이터에 주로 이 전략을 사용합니다.
캐시에 데이터 저장
기억해야 할 두 번째 수준 캐시에 대한 또 다른 중요한 세부 사항은 Hibernate가 클래스 자체의 객체를 저장하지 않는다는 것입니다. 문자열, 숫자 등의 배열로 정보를 저장합니다.
그리고 개체 식별자는 이 정보에 대한 포인터 역할을 합니다. 개념적으로 이것은 개체의 ID가 키이고 데이터 배열이 값인 맵과 같은 것입니다. 다음과 같이 상상할 수 있습니다.
1 -> { "Ivanov", 1, null , {1,2,5} }
2 -> { "Petrov", 2, null , {1,2,5} }
3 -> { "Sidorov", 3, null , {1,2,5} }
각 개체가 차지하는 추가 메모리 양을 고려하면 매우 합리적입니다.
위의 내용 외에도 Entity 클래스의 종속성도 기본적으로 캐시되지 않는다는 점을 기억해야 합니다. 예를 들어 위의 클래스인 Employee를 고려하면 가져올 때 작업 컬렉션은 두 번째 수준 캐시가 아닌 데이터베이스 에서 검색 됩니다 .
종속성도 캐시하려면 클래스가 다음과 같아야 합니다.
@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
@Id
private Integer id;
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Task> tasks;
}
그리고 마지막 세부 사항 - 두 번째 수준 캐시에서 읽기는 원하는 개체가 첫 번째 수준 캐시에서 발견되지 않은 경우에만 발생합니다.
캐시 모드
Hibernate는 매우 유연한 캐싱 관리를 허용합니다. 각 개별 세션 또는 각 데이터베이스 요청에 대해 캐시 모드를 설정할 수 있습니다.
다음과 같은 5가지 모드가 있습니다.
- 얻다
- 무시하다
- 정상
- 놓다
- 새로 고치다
아래 표는 그들의 작업을 설명합니다.
캐시 모드 | 설명 |
---|---|
얻다 | 데이터는 캐시에서 읽히지만 추가되지는 않습니다. |
무시하다 | 세션은 캐시와 상호 작용하지 않습니다. |
정상 | 캐시에서 데이터를 읽어 캐시에 추가합니다. |
놓다 | 데이터는 캐시에서 가져오지 않고 추가됩니다. |
새로 고치다 | 데이터는 캐시에서 가져오지 않고 추가됩니다. 이 모드에서는 hibernate.cache.use_minimal_puts 설정이 추가로 사용됩니다. |
세션에 대한 캐시 모드 설정의 예:
session.setCacheMode(CacheMode.GET);
Employee director = session.createQuery("from Employee where id = 4").uniqueResult();
또한 세션 및 요청에 대한 모드 설정의 예:
session.setCacheMode(CacheMode.GET);
Query query = session.createQuery("from Employee where id = 4");
query.setCacheMode(CacheMode.IGNORE); // Ignore cache work for this request
Employee director = query.uniqueResult();