2010-10-19 26 views
9

En EHCache, ¿hay alguna manera de implementar algún tipo de escucha de db donde el código se actualizará automáticamente si los datos no están sincronizados? (por ejemplo, tan pronto como el usuario solicite datos, el cache revisa si los datos están fuera de sincronización, si es así ... se actualiza y devuelve los datos, si no ... solo devuelve los datos del caché) Si alguien puede señalarme qué parte de la especificación destaca este uso, ¡sería increíble!EHCache refresh

El objetivo es proporcionar siempre los últimos datos al usuario. Así que supongo que un mecanismo de actualización cronometrada no funcionará, ya que los datos pueden cambiar en cualquier momento.

Ehcache no es obligatorio el uso en mi caso, por lo que cualquier mecanismo que satisface esta será bienvenida ...

Gracias !!

Respuesta

3

Para EhCache this es lo que creo que usted está buscando. Si no desea realizar una actualización cronometrada (aunque es una solución simple), los desencadenadores o una actualización basada en el bus de mensajes sería el camino a seguir. Puede realizar algunas estadísticas y ver la frecuencia de actualización una vez que se ha establecido la activación y cambiar a una actualización temporizada con suficiente frecuencia para satisfacer Nyquist.

+0

Lamentablemente, el enlace ya no funciona. – emanciperingsivraren

+0

este es el enlace de trabajo http://www.ehcache.org/documentation/2.8/recipes/expiration.html – ChainLooper

3

Lo hice usando ehcache-spring-annotations. Estos son mis dependencias en el pom.xml experto

<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> 

obras @Cacheable, pero desafortunadamente @TriggersRemove no funciona. La solución alternativa es invalidar el caché de forma manual. Aquí está mi ejemplo de uso:

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

... 
} 

La aplicación KeyGenerator puede ser:

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

} 

En la configuración de 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> 

Espero que sea útil.