2017-04-21 1 views
1

J'ai besoin d'une compréhension de base de la fonction de cache du ressort. Je veux construire un cache cache et resyncer en tant que bean planifié, afin de renouveler le cache à la demande, lorsque des changements se produisent. Disons, j'ai un AccountClient avec getAccount(String id), qui récupère un Account à partir d'une API très lente. Donc, fondamentalement, je peux faireRéchauffement du cache de démarrage du ressort

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

et tout fonctionne bien. Maintenant, je veux réchauffer le cache, et de plus, j'ai obtenu un getNewOrChangedAccounts(), qui récupère les ID des comptes modifiés de ma banque de données lente.

Voici donc mon approche:

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); 
    } 
} 

preuve donc je peux, ce processus se met en marche et fait quelque chose. Cependant, quand je frappe mon API, je vois le premier hit aller au backend lent, même si ma synchronisation va sur toutes les entrées du backend.

Je crois avoir mal compris certains détails de l'API de mise en cache de printemps, alors comment puis-je y parvenir?

Répondre

1

De documentation pour @CachePut:

Contrairement à l'annotation @Cacheable, cette annotation ne la cause à sauter la méthode recommandée. Au contraire, cela provoque toujours l'invocation de la méthode et son stockage dans le cache associé.

Ainsi, votre méthode annotée avec @CachePut doit renvoyer les données dans le cache:

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

Voir aussi cette question: Spring Cacheable vs CachePut?

+0

thx! J'ai oublié de retourner la valeur! –

+0

après quelques jours, ça ne marche toujours pas pour une raison quelconque ... est-ce que le cache fonctionne différemment pour les requêtes? –

+0

cela ressemble à travailler en utilisant 'CacheManager' directement, en annotant simplement avec @CachePut et le retour n'est pas suffisant –