这个用例可以在ehcache中解决吗?

时间:2012-01-06 08:00:22

标签: java caching asynchronous synchronization ehcache

我想使用ehcache不仅作为缓存,而且作为脏对象的容器,当对象被逐出/过期时,我想要刷新到我的数据库。在正常处理期间,我使用密钥在ehcache中查找。如果key不存在,我从数据库读取数据并将其放入ehcache。该值实际上是我修改的复杂对象。当ttl / idle time / overflow条件发生时,我看到调用了CacheEventListener回调。但是有一个大问题。从缓存中删除键值后调用notifyElementExpired。所以有竞争条件。如果我在notifyElementExpired中执行刷新脏值以缓存的任务,同时在另一个线程中读取相同的密钥,则会出现同步问题。第二个线程将无法在ehcache中找到该对象,因此将转到数据库,而另一个线程仍在准备刷新。

我尝试使用直写式ehcache进行实验,我认为这也不起作用。

这里有解决方案吗?

即使它涉及除ehcache之外的其他一些缓存机制,我也非常感谢这个问题的良好解决方案。

谢谢

1 个答案:

答案 0 :(得分:1)

如果你对纯粹的内存缓存感到满意,我建议扩展Google Guava库的CacheLoader,例如:

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


当然,您需要通过适当的异常处理来整理它。

我发现guava比正确配置ehcache要简单明了。