2017-04-21 13 views
1

스프링 캐시 기능에 대한 기본적인 이해가 필요합니다. 변경이 발생하면 캐시를 갱신하기 위해 예정된 빈처럼 캐시 워머와 다시 동기화기를 만들고 싶습니다.스프링 부트 캐시 워밍업

매우 낮은 API에서 Account을 가져 오는 은 getAccount(String id)입니다. 그래서 기본적으로 할 수 있어요

@Cachable(cacheNames = "account", key = "#id", sync = true) 
public Account getAccount(String id) { 
    //... 
} 

모두 잘 작동합니다. 이제 캐시를 예열하고 더 느린 데이터 저장소에서 변경된 계정의 ID를 검색하는 getNewOrChangedAccounts()이 있습니다.

그래서 여기 내 접근 방식 :

public class AccountCacheManager { 

    //... 

    @Scheduled(initialDelay = 3000L, fixedRate = 10000L) 
    public void sync() { 
     List<Account> modifiedAccounts = accountClient.getNewOrChangedAccounts(); 

     modifiedAccounts.getAccounts().parallelStream() 
       .forEach(account -> { 
        //delete old entry 
        evictAccount(account.getId()); 
        //store new entry 
        putAccount(account.getId()); 

       }); 


     log.info("finished resync"); 
    } 

    @CacheEvict(cacheNames = "account", key = "#id") 
    public void evictAccount(String id) { 
     log.debug("evicting account {}", id); 
    } 

    @CachePut(cacheNames = "account", key = "#id") 
    public void putAccount(String id) { 
     log.debug("storing account {}", id); 
     accountService.getAccount(id); 
    } 
} 

그래서 증거 할 수있는,이 과정을 시작하고 무언가를 가져옵니다. 그러나 내 API를 클릭하면 내 동기화가 백엔드의 모든 항목을 거쳤더라도 첫 번째 히트가 느린 백엔드로 이동하는 것을 볼 수 있습니다.

스프링 캐싱 API의 일부 세부 사항을 오해 한 것 같은 느낌이 들지만 어떻게 해결할 수 있습니까? @CachePut에 대한 documentation에서

답변

1

다음 @Cacheable 주석과는 대조적으로

,이 주석이 원인이 권장 방법이 제외 될하지 않습니다. 오히려 항상 메소드가 호출되고 그 결과가 연관된 캐시에 저장됩니다.

그래서 @CachePut 주석 당신의 방법은 캐시에 데이터를 반환해야합니다 :

@CachePut(cacheNames = "account", key = "#id") 
    public Account putAccount(String id) { 
     log.debug("storing account {}", id); 
     return accountService.getAccount(id); 
    } 

참조 또한이 질문 : Spring Cacheable vs CachePut?

+0

들으! 나는 가치를 잊었다! –

+0

몇 일 후, 그것은 여전히 ​​어떤 이유로 작동하지 않습니다 ... 요청에 대해 분리 된 캐싱이 있습니까? –

+0

'CacheManager'를 직접 사용할 때처럼 작동하는 것처럼 보입니다. 단순히 @CachePut으로 주석을 달고 반환만으로는 충분하지 않습니다. –