Ehcache - 在数据不存在时使用SelfPopulatingCache

时间:2010-12-17 18:20:44

标签: java ehcache

我正在使用EhCache的装饰器SelfPopulatingCache并且在缓存尝试加载新条目时遇到问题,但它不存在(即它在数据库中不存在)。因此,缓存会将null值放入缓存中,以解除对密钥上任何其他内容的阻止,但随后下一个线程将执行相同的数据库调用,因为它从缓存中收到“null”。这意味着它认为需要加载条目 - 即使实际上它是空的,因为数据不存在于任何地方。我觉得我做错了什么。

(伪代码)

Value v = cache.get(key); // multiple threads will block here
if (v == null)
   cache.put(key, getValueFromDB()); // this might put a null value

我目前的解决方案是不放空,而是放置占位符Object并检查它。

Value v = cache.get(key);
if (v == null)
   cache.put(key, getValueFromDB());
else if (v == NOENTRYOBJECT)
   return null;
else
   return v;

思想?

3 个答案:

答案 0 :(得分:3)

我们做类似的事情。在我们的例子中,如果请求的密钥与有效项不对应,我们将Boolean.FALSE输入缓存。它基本上告诉调用代码它要求的密钥与任何数据都不匹配。您需要在第一次请求该密钥时对数据库进行一次调用,以发现它与有效数据不对应,但后续调用不会进行数据库查找。当然,如果数据曾经输入到该密钥的数据库中,则需要确保使该缓存条目无效(否则即使有可用的实际数据,您也将返回Boolean.FALSE。)

不确定我的回答是否有多大帮助(这不是一种替代方法),但它至少证实了你的方法并不孤单。

顺便说一句,我不认为这是EHCache的SelfPopulatingCache独有的。

答案 1 :(得分:1)

如果项目的 KEY 完全存在于缓存中,而不是 VALUE ,则典型模式不会重新检查数据库。

此处的模式在ehcache文档中有所描述:Caching Empty Values

通常情况下,但并非总是如此,get会返回Element,因此如果以前曾调用过get(id)put(id, value)也不会为空,即使value为null也是如此。

请注意,这取决于缓存实现。 ehcache文档似乎表明它应该始终有效,但BlockingCache(及其后代)does NOT allow putting null values into the cache。基本ehcache Cache对象允许将空值存储在缓存中(许多示例和自定义实现也是如此)。

总而言之,我认为您已经拥有的解决方案(占位符值对象)也可以,并且应该实现与ehcache base Cache类和文档相同的结果。

答案 2 :(得分:0)

我想你需要查看CacheElementFactory。我已经在春天实现了这个项目,我正在努力将负载信息请求到缓存中,如果有缓存未命中,则尝试从数据库加载它。我不记得具体说明了我对此做了什么,我认为不幸的是,这会导致向数据库发出请求丢失密钥的每个传递请求。