2014-05-23 9 views
2

저는 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; 
} 

돌아갑니다 컨트롤러 방법에서 제거하고 그들과 함께

  1. 방문 /incrementcounter
  2. 하나 개의 브라우저 탭에서 /viewcounter를 방문하여 즉시 reque을 시작 후에 다시 추가 ST,
  3. 방문 /viewcounter

테스트

Expected result: 2 
Actual result without caching: 2 
Actual result with caching: 1 

결과 다른 탭에 /incrementcounter를 방문 결과, 네 잘못과 캐싱?

+0

아니, 내가 기대하는 것입니다. 선택하는 순간의 'count'는 1입니다 (나중에 업데이트합니다). 이 값은 반환되고 캐시됩니다. –

+0

@ M.Deinum 2 단계의 결과에 대해 이야기하고 있다고 생각합니다. 예, 그 시점에서/viewcounter는 1의 값을 표시해야합니다. 그러나 3 단계의 결과에 대해 이야기하고 있습니다.이 요청은/incrementcounter에 대한 두 번 호출이 실행될 때까지 시작되지 않으므로 올바른 결과는 값 2 여야합니다. – Blaine

+0

3 단계의 경우 값은 캐시 된 값 그대로 1입니다. –

답변

1

캐시 추상화에는 잠금 기능이 없습니다. 당신은 not the first one asking for it이고 우리는 이미 그것을 지원하기 위해 필요한 내부적으로 중요한 브레인 스토밍을 가졌습니다. 그것은 단순하지 않고 그러한 추상화에서 잠금 장치를 가지고 노는 것은 매우 까다 롭습니다. 특히 "일반적인"방식으로 특히 그렇습니다. 또한 캐시 공급 업체는 이러한 종류의 사용 사례를 지원하기 위해 상당한 양의 리소스를 사용하며 그 이유가 있습니다.

이 순간에 가장 좋은 추측은 이러한 기능을 원한다면 캐시가 트랜잭션이어야한다는 것입니다. 추상화와 함께 사용할 때 약간의 문제가 있지만, 지금은 SPR-11540을 확인하십시오.