在数据库更新过程中绕过缓存

问题描述

我已使用加载程序配置了cache2K,因此将从后端数据存储区检索缓存中不存在的密钥。我的模式在更新持久化值时会先更新数据库,然后通过数据库更改通知异步更新缓存。有什么方法可以防止从数据库更新到缓存被通知更改之间的陈旧读取?

我在考虑一种机制,其中陈旧的数据保留在缓存中,但是在下一次从缓存中检索实体时有效地过期/加载了。我想将密钥保留在缓存中,但是在任何人尝试访问该值时强制加载。我尝试设置 keepDataAfterExpired = true ,但是,似乎没有任何效果

解决方法

您是否尝试过锁定表的持续时间?您也可以在该网站上阅读更多内容: https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html

,

一种可能的解决方案(休眠方式就是这样做)是将状态与值一起存储。例如。使用包装器类获取值:

  abstract class ValueOrUpdating<V> {  }

  class Value<V> extends ValueOrUpdating<V> {
    V value;
  }

  class Updating extends ValueOrUpdating<Void> {
  }

要绕过密钥的缓存,您可以这样做:

  cache.put(key,new Updating();

要访问值:

  V read(K key) {
    ValueOrUpdating<V> v = cache.get(key);
    if (v instanceof Updating) {
      return load(key);
    }
    return ((Value<V>) v).value;
  }

这种方法非常简单,并且适用于每个缓存。

我尝试将keepDataAfterExpired设置为true,但这似乎没有任何作用

使用cache2k的更复杂的解决方案可以使用 keepDataAfterExpiredAdvancedCacheLoader。这样,您可以利用其他cache2k功能,例如提前刷新和弹性。还可以避免直接调用加载程序,因此缓存统计信息不会有缺陷。我在这里输入了一些用于此想法的代码:https://github.com/cache2k/cache2k-qa/blob/master/java8/src/test/java/StackOverflow63752162Test.java