【问题标题】:Trigger Guava cache refresh when a table is updated更新表时触发 Guava 缓存刷新
【发布时间】:2019-06-05 19:05:14
【问题描述】:

目前我正在使用 ClientDAO.getClients() 从数据库中获取客户端列表,并使用 guava 进行缓存,刷新周期如下所示 30 分钟

private List<String> getClients() {
        final Supplier<List<String>> supplier = () ->  ClientDAO.getClients();
        Suppliers.memoizeWithExpiration(supplier, 30, TimeUnit.MINUTES);
        return supplier.get();
    }

我们有不同的应用程序更新client 表和另一个应用程序从client 表中读取并如上所述缓存,并且这两个应用程序之间没有Restful 或任何类型的api 通信。每当更新数据库中相应的client 表而不是在特定时间窗口 30 分钟刷新时,有什么方法可以触发此缓存更新?

【问题讨论】:

  • 您使用的是哪个 RDBMS?从技术上讲,可能可以通过数据库触发器通知缓存应用程序,但这只能解决这两个应用程序不相互通信的问题。
  • 我正在使用 SQL Server 2008 r2,是的,这两个应用程序不相互通信

标签: java caching guava


【解决方案1】:

所以从这个问题我会假设:

  • 有两个应用程序AB
  • 有一个客户表 - 我们称之为table X
  • Atable X 读取和缓存数据
  • B 将数据写入table X

A 需要知道B 何时写入table X,以便A 可以更新它的缓存数据。

选项 1

如果您控制AB,您可以扩展行为 - 当B 写入数据库并且写入成功时,BA 触发一个事件(例如调用 REST 端点)并且A 将知道更新其缓存。

选项 2

如果您无法控制 B,但可以控制 ADB,则可以使用 DB 作为集成点 - 这是遗留应用程序的常用方法 - DB 是应用程序可以集成的唯一地方。

因此,您可以再次应用 BA 触发事件的相同概念,但这次事件(由触发器启动)存储在 @987654345 的表中@ 并且 REST 调用是从数据库本身使用内部过程进行的。

直接的方法是:

  • B 将数据写入table X
  • table X 有一个 insert trigger,它在事件存储表中执行一条 INSERT 语句(我们称之为 UPDATE_CACHE_EVENT

您的“update_cache_event”现在已被触发(例如,保存在该表中),从此时起您有更多选择:

  • A 可以每秒监控这个表,并在写入新事件时触发它的缓存更新

  • A 公开 REST API,从 DB 调用 - 例如在 SQL Server 中编写一个过程,监控UPDATE_CACHE_EVENT 表并调用A 的 REST API。

一些想法:

  • 不要使用触发器本身来调用外部 API,为此使用专用过程
  • 触发器具有性能损失(例如,每次写入 table X 都会调用另一个插入事件表),因此在设计解决方案时应考虑这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    相关资源
    最近更新 更多