这个用例可以在ehcache中解决吗?
我想使用ehcache不仅作为一个缓存,而且作为一个容器的脏对象,当对象被驱逐/过期时,我想刷新到我的数据库。在正常处理期间,我使用密钥在ehcache中查找。如果密钥不存在,我从数据库读取数据并将其放入ehcache。该值实际上是一个复杂的对象,我修改。当ttl /空闲时间/溢出情况发生时,我看到CacheEventListener回调被调用。但是有一个很大的问题。 notifyElementExpired在从缓存中删除键值后调用。所以有一个竞争条件。如果我执行将脏值刷新到notifyElementExpired中的缓存任务并同时在另一个线程中读取相同的密钥,则会出现同步问题。第二个线程将不会在ehcache中找到该对象,因此将转到数据库,而另一个线程仍在准备刷新。这个用例可以在ehcache中解决吗?
我试着用写通过ehcache试验,我不认为这也工作。
有没有解决方法?
我真的很感谢这个问题的好解决方案,即使它涉及到一些其他的缓存机制而不是ehcache。
感谢
如果你确定与一个纯粹的内存缓存,我建议延长Google Guava库的缓存加载器,例如:在使用之后
public class DBLoader extends CacheLoader<String, String> {
@Override
public String load(String key) throws Exception {
// load a value from the database
return value;
}
}
,是这样的:
private LoadingCache<String, String> dbCache = CacheBuilder.newBuilder()
.expireAfterWrite(CACHE_EXPIRE_IN_SECONDS, TimeUnit.SECONDS)
.build(new DBLoader());
String value = dbCache.get(someKey);
当然,您需要整理好适当的异常处理。
我发现番石榴比正确配置ehcache要简单得多。
番石榴有它自己的竞争条件:https://github.com/google/guava/issues/1881 – CurtainDog 2015-02-10 05:37:00
我自己找不到任何答案。所以我继续自己解决它!这里是我博客的解决方案 - http://blog.readypulse.com/2012/01/08/ehcache-as-a-true-persistent-store-backed-cache/ – 2012-01-08 21:53:20
好的作品TVinodGupta。作为一个友好的提醒,你可以请你自己发表问题的答案,然后接受答案,以便我们可以关闭这个问题?另外,如果他们解决了您的问题,则需要接受以前问题的答案。 – Zecas 2012-05-28 14:22:31