2010-10-19 18 views
9

In EHCache, c'è un modo per implementare un qualche tipo di listener db in cui il cahce si aggiornerà automaticamente se i dati non sono sincronizzati? (ad esempio, non appena l'utente richiede i dati, il cahce controlla se i dati non sono sincronizzati, se sì ... aggiorna se stesso e restituisce i dati, in caso contrario ... restituisce semplicemente i dati dalla cache) Se qualcuno può indicami quale parte delle specifiche evidenzia questo uso, sarebbe fantastico!EHCache refresh

L'obiettivo è fornire sempre all'utente i dati più recenti. Quindi suppongo che un meccanismo di aggiornamento a tempo non funzioni in quanto i dati possono cambiare in qualsiasi momento.

EHCache non è obbligatorio utilizzare nel mio caso, in modo che qualsiasi meccanismo che soddisfa questa sarà il benvenuto ...

Grazie !!

risposta

3

Per EhCache this è quello che credo tu stia cercando. Se non ti piacerebbe fare un aggiornamento temporizzato (anche se si tratta di una soluzione semplice), i trigger o un aggiornamento basato sul bus dei messaggi sarebbe la strada da percorrere. È possibile eseguire alcune statistiche e vedere la frequenza di aggiornamento una volta che il trigger è stato stabilito e passare ad un aggiornamento a tempo con frequenza sufficiente a soddisfare Nyquist.

+0

Sfortunatamente il collegamento non funziona più. – emanciperingsivraren

+0

questo è il link di lavoro http://www.ehcache.org/documentation/2.8/recipes/expiration.html – ChainLooper

3

L'ho fatto utilizzando le annotazioni ehcache-spring. Queste sono le mie dipendenze nel pom.xml Maven

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-core</artifactId> 
    <version>3.0.5.RELEASE</version> 
</dependency> 
<dependency> 
    <groupId>net.sf.ehcache</groupId> 
    <artifactId>ehcache-core</artifactId> 
    <version>2.2.0</version> 
</dependency> 
    <dependency> 
    <groupId>com.googlecode.ehcache-spring-annotations</groupId> 
    <artifactId>ehcache-spring-annotations</artifactId> 
    <version>1.2.0-M1</version> 
</dependency> 

opere @Cacheable, ma purtroppo @TriggersRemove non funziona. La soluzione alternativa è invalidare manualmente la cache. Ecco il mio esempio di utilizzo:

package com.company.project.dao; 

import java.util.List; 

import net.sf.ehcache.CacheManager; 
import net.sf.ehcache.Ehcache; 

import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.FactoryBean; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.stereotype.Component; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import com.company.project.domain.Parent; 
import com.company.project.domain.Child; 

import com.googlecode.ehcache.annotations.Cacheable; 
import com.googlecode.ehcache.annotations.KeyGenerator; 
import com.googlecode.ehcache.annotations.Property; 

@Component("Example") 
public class EhcacheExample { 

    @Autowired 
    @Qualifier("ehCacheManager") 
    private FactoryBean<CacheManager> ehCacheManager; 

    public void createParen(Parent parent) { 
     cleanCache(parent); 
     create(parent); 
    } 

    private void cleanCache(Parent parent) { 
     try { 
      CacheManager cacheManager = ehCacheManager.getObject(); 
      Ehcache ehcache = cacheManager.getEhcache("myCache"); 
      ehcache.remove(parent.getChild().hashCode()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Cacheable 
    ( cacheName = "myCache", 
     keyGenerator = @KeyGenerator (   
      name = "com.company.project.util.ChildCacheKeyGenerator",     
      properties = @Property(name="includeMethod", value="false") 
     ) 
    ) 
    public List<SerieRecording> getParentsByChild(Child child) { 
     return ...; 
    } 

    @Override 
    public void deleteParentById(long id) { 
     Parent parent = findById(id); 
     cleanCache(parent); 
     delete(parent); 
    } 

... 
} 

L'implementazione KeyGenerator può essere:

package com.company.project.util; 

import java.io.Serializable; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import com.company.project.domain.Child; 

import com.googlecode.ehcache.annotations.key.AbstractCacheKeyGenerator; 


public class ChildCacheKeyGenerator extends AbstractCacheKeyGenerator<Serializable> { 

    Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Override 
    public Serializable generateKey(Object... data) { 

     if (data[0] instanceof Child) { 
      Child child = (Child)data[0]; 
      return child.hashCode(); 
     } 
     new IllegalArgumentException(); 
     return null; 
    } 

} 

Nella configurazione Primavera:

<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" > 
    <property name="configLocation" value="classpath:config/ehcache-methods.xml"/> 
</bean> 

EHCache-methods.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="ehcache.xsd"> 

    <cache name="myCache" eternal="false" 
     maxElementsInMemory="12600" overflowToDisk="false" diskPersistent="false" 
     timeToIdleSeconds="0" timeToLiveSeconds="1800" 
     memoryStoreEvictionPolicy="LRU" /> 

</ehcache> 

Spero sia utile.