首页 > 解决方案 > 防止缓存在更新返回的对象时不同步

问题描述

我正在使用 vb.net 我有一个 Web 应用程序,它经常使用缓存来保存数据以便更快地访问。这是一个 MemoryCache,通过引用检索对象。这是一个相当大的项目,其中缓存内的对象类型是未知的。缓存中存在的许多对象都持有与数据库内部存在的信息相对应的内部属性。我的问题是,当我修改从数据库请求的对象(但从缓存中接收)时,我更改了引用处的值。

这是解释此问题的场景:

  1. 我请求一个数据列表,缓存有它,所以它是通过引用从缓存中返回的。
  2. 我在收到的列表中进行了一些更改(比如我更改了第 3 项的名称),现在在将其发布到数据库之前,我需要将其与原始列表进行比较。不存在本地副本,因此再次从数据库请求数据(但从缓存中接收)
  3. 我比较了数据(来自 1. 和 2.),因为数据指向相同的参考我没有发现任何差异(没有)。

当我在第 3 点进行第二次 db 调用时,我在不知情的情况下从缓存中获取了数据,我该如何解释这一点并确保我收到的数据始终是数据库中的数据的镜像?

有什么好的方法可以检测缓存中的数据何时被修改?(没删,只是改了)

我看过 CacheEntryChangeMonitor 但到目前为止只能检测到数据何时或即将被删除,而不是何时更新内部变量。

另一种解决方案是在将对象插入缓存时创建对象的校验和,因为我不知道对象的类型,也不知道它包含哪些变量(因类型而异)我不知道不知道如何以一种好的方式做到这一点。

(函数是这样制作的:Function placeInCache(Of T)(obj As CacheKeeper(Of T)) As T为了支持我们所有可能的对象)

标签: .netvb.netcachingreference

解决方案


这里有许多不同的概念和问题,所以我将尝试解决它们:

  1. 如果您正在更改影响缓存对象的某些内容,理想情况下,您应该有一种简单的方法直接使数据无效。例如,如果您更改第 3 项的名称,您应该有一种简单的方法可以知道哪些缓存项无效并直接刷新它们
  2. 可以将缓存参数添加到任何“获取”方法,即“从数据库获取并绕过缓存”
  3. 您必须非常小心缓存,如果您不小心,最终可能会增加复杂性而无济于事。使用较短的缓存时间和短期内不是最新的数据(陈旧数据)可能更容易生活
  4. 您可以拆分缓存对象,以便缓存单个对象并从缓存对象重建列表,而不是缓存整个列表。这可能更容易使过时的缓存条目失效
  5. 如果缓存中的条目非常大并且从数据库重新创建的速度很慢,您可以使用一些基于校验和/更新日期等的过时检查,并通过一种机制调用缓存,该机制可以轻松检查日期以与缓存进行比较返回或刷新之前的项目。

推荐阅读