저는 Spring 4.0.3을 사용 중이며 EhCache 2.8.1에 의해 뒷받침되는 캐시 추상화 기능을 사용하고 있습니다.축출이 관련되어있을 때 스프링의 캐시 주석을 안전하게 사용할 수 있습니까?
메서드 레벨 주석 @Cacheable
및 @CacheEvict
은 스레드를 편집하는 동안 캐시를 제대로 잠그지 않아 스레드 안전 문제가 발생할 수 있다고 우려했습니다. 내 테스트는 그것을 확인하는 것 같습니다. 제 질문은 프레임 워크를 잘못 사용하거나 테스트 결과를 잘못 해석합니까? 또는 주석으로 인해 캐시가 제대로 잠기지 않는다는 결론을 내렸으므로 @CacheEvict
을 사용한다고해서 향후 읽기가 유효하다는 보장을하지 못합니까?
테스트 :
는 카운터 값
<cache name="counter"
eternal="true"
maxElementsInMemory="1"/>
에게 캐시 ehcache.xml의 항목을 작성 카운터 값
create table counter
(
counter integer
);
insert into counter values(0);
를 저장하는 데이터베이스 테이블 만들기 Spring 컨트롤러에서 두 개의 요청 매핑 메소드 만들기 - 먼저 캐시 주석에 - 하나는 두 개의 다른 시나리오에서이 세 가지 단계를 수행 카운터의 값을 읽고 긴 지연 후 반환하고 다른 하나는 값을 증가하고 신속하게
@RequestMapping("/viewcounter")
@ResponseBody
@Cacheable(value = "counter", key = "1")
public int readCounter() {
int count = dao.selectInteger("select counter from counter");
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return count;
}
@RequestMapping("/incrementcounter")
@ResponseBody
@CacheEvict(value = "counter", key = "1")
public int incrementCounter() {
dao.update("update counter set counter = counter + 1");
int count = dao.selectInteger("select counter from counter");
return count;
}
돌아갑니다 컨트롤러 방법에서 제거하고 그들과 함께
- 방문
/incrementcounter
- 하나 개의 브라우저 탭에서
/viewcounter
를 방문하여 즉시 reque을 시작 후에 다시 추가 ST, - 방문
/viewcounter
테스트
Expected result: 2
Actual result without caching: 2
Actual result with caching: 1
결과 다른 탭에 /incrementcounter
를 방문 결과, 네 잘못과 캐싱?
아니, 내가 기대하는 것입니다. 선택하는 순간의 'count'는 1입니다 (나중에 업데이트합니다). 이 값은 반환되고 캐시됩니다. –
@ M.Deinum 2 단계의 결과에 대해 이야기하고 있다고 생각합니다. 예, 그 시점에서/viewcounter는 1의 값을 표시해야합니다. 그러나 3 단계의 결과에 대해 이야기하고 있습니다.이 요청은/incrementcounter에 대한 두 번 호출이 실행될 때까지 시작되지 않으므로 올바른 결과는 값 2 여야합니다. – Blaine
3 단계의 경우 값은 캐시 된 값 그대로 1입니다. –