有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java EhCache CacheLoaderWriter。缓存项过期后未调用load()

我使用CacheLoaderWriter创建了简单的EhCache测试:

Cache<Long, BigInteger> cache = cacheManager.getCache("aCache3", Long.class, BigInteger.class);
assertEquals(cache.get(2L), BigInteger.ONE);
Thread.sleep(6000);
assertEquals(cache.get(2L), BigInteger.ONE); // fails here with null!=1

当键为2L的缓存项在睡眠后过期时,缓存将停止。get(2L)返回空值。在我看来,它应该首先调用CacheLoaderWriter。load()方法从SoR中获取正确的值,然后返回它

你能解释一下为什么会发生这种情况,以及我如何改变这种行为吗?是否有其他配置选项,或者我是否遗漏了什么

ehcache。xml:

<cache alias="aCache3" uses-template="default">
    <key-type>java.lang.Long</key-type>
    <value-type>java.math.BigInteger</value-type>
    <expiry><ttl unit="seconds">4</ttl></expiry>
    <loader-writer >
        <class >com.example.jeight.ehcache.MapCacheLoaderWriter</class>
    </loader-writer>
    <resources>
        <heap unit="entries">10</heap>
        <disk persistent="false" unit="MB">10</disk>
    </resources>

MapCacheLoaderWriter:

public class MapCacheLoaderWriter implements CacheLoaderWriter<Long, BigInteger> {

    private Logger LOGGER = LoggerFactory.getLogger(getClass());

    private Map<Long, BigInteger> map;

    public  MapCacheLoaderWriter() {
        map = new HashMap<>();
    }

    @Override
    public void delete(Long k) throws Exception { }

    @Override
    public void deleteAll(Iterable<? extends Long> ks) throws BulkCacheWritingException, Exception {    }

    @Override
    public BigInteger load(Long k) throws Exception {
        LOGGER.info("Cache load: " + k);
        if (!map.containsKey(k)) {
            BigInteger v = fib(k);
            map.put(k, v);
        }
        return map.get(k);
    }

    @Override
    public Map<Long, BigInteger> loadAll(Iterable<? extends Long> ks) throws BulkCacheLoadingException, Exception {
        Map<Long, BigInteger> result = new HashMap<>();
        for (Long k : ks) {
            load(k);
        }
        return result;
    }

    @Override
    public void write(Long k, BigInteger v) throws Exception {
        LOGGER.info("Cache write: " + k + " " + v);
        map.put(k, v);
    }

    @Override
    public void writeAll(Iterable<? extends Entry<? extends Long, ? extends BigInteger>> kvMap)
        throws BulkCacheWritingException, Exception {
        for (Entry<? extends Long, ? extends BigInteger> k : kvMap) {
            write(k.getKey(), k.getValue());
        }
    }

    private BigInteger fib(long k) {
       // some code returning a non-null value
    }
}

共 (1) 个答案

  1. # 1 楼答案

    这是一个需要在Ehcache中修复的bug

    谢谢你的报道

    要避免这个问题,你唯一能做的就是将缓存限制在一层——要么是堆(如果你可以使用较小的条目集),要么是磁盘(如果你可以使用每个get上添加的反序列化)