EHCache refresh
In EHCache, is there a way to implement some kind of a db listener where the cahce will auto update if the data is out of sync? (开发者_如何学编程e.g as soon as the user requests for data, the cahce checks if the data is out of sync, if yes...updates itself and returns the data, if not...just return the data from the cache)If someone can point me which part of the specification highlights this use, that would be awesome!
The goal is to always provide the latest data to the user. So I am guessing a timed refresh mechanism will not do as the data can change anytime.
EHCAche is not mandatory to use in my case, so any mechanism that satisfies this will be most welcome...
Thanks!!
For EhCache this is what I believe you are looking for. If you would not like to do timed refresh (even though it is a simple solution), triggers or a message bus based update would be the way to go. You can perform some statistics and see update frequency once the triggering has been established and switch to a timed update with sufficient frequency to satisfy Nyquist.
I did that using ehcache-spring-annotations. These are my dependencies in the maven pom.xml
<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>
@Cacheable works, but unfortunately @TriggersRemove doesn't work. The workaround is to invalidate the cache manually. Here is my example of usage:
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);
}
...
}
The KeyGenerator implementation can be:
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;
}
}
In the Spring configuration:
<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>
I hope it is useful.
精彩评论