0

我正在使用javax 缓存数据库。我使用缓存的 API 来获取/放置/删除实体,并且数据库位于此缓存后面。为此,我正在使用CacheLoaderCacheWriter

因此,以下是与缓存 API 等效的 SQL 构造

  1. 选择 -> 获取
  2. 插入 -> 放
  3. 删除 -> 删除

如果我的缓存中已经存在条目并且我更新了它,那么我将只获得该值的“写入”方法。但是,由于该值存在于数据库中,我需要使用 UPDATE 查询。

如何确定在缓存的“放置”操作中执行哪个数据库操作?

注意:从性能的角度来看,UPSERT 不是好的选择。

4

2 回答 2

0

我能想到几种方法。基本上这些是以下变化:

数据库中的元数据

在一个实体中,我通常有附加字段,它们是插入和更新的时间戳以及由对象到关系映射器 (ORM) 处理的修改计数器。这对于调试非常有用。CacheWriter可以检查是否设置了插入时间戳,如果是,则为更新,如果不是,则为插入。

如果您的应用程序正在通过缓存读取最新内容并写入其修改版本,则该值是否同时被驱逐并不重要。

如果您的应用程序在修改之前没有读取数据或者这种情况经常发生,我建议缓存一个类似insertedAlready. 这导致了三路逻辑:已激活,未插入,不在缓存中=还不知道。在字母情况下,您需要在更新或插入缓存写入器之前进行读取。

仅缓存中的元数据

缓存对象存储附加数据,无论该对象之前是否从数据库中读取。喜欢:

class CachedDbValue<V> {
  boolean insertedAlready;
  V databaseContent;
}

面向应用程序的代码需要将数据库数据包装到缓存值中。

旁注1:不要从缓存中读取对象并直接修改实例,始终制作副本。直接修改对象可能对不同的 JCache 实现产生不同的不良影响。还要在这里查看我的解释:javax.cache 按引用存储与按值存储

旁注 2:您正在自己构建缓存 ORM 层。也许使用现有的。

于 2021-07-14T08:10:36.887 回答
0

如果您将值放入缓存中,您可以首先检查密钥是否已经存在,在这种情况下您需要更新。如果密钥不存在,则需要 INSERT。听起来您可以从具有 L2 缓存的 ORM 中受益,例如 Hibernate,它可以为您处理所有这些场景(以及更多场景)。

于 2021-07-13T14:09:15.903 回答