【发布时间】:2014-10-29 19:48:40
【问题描述】:
我已经使用 App Engine 几年了,而 HDR 似乎一次又一次出现的一个问题是,当您在一个屏幕上更新数据时,有时会在读取时检索旧数据-如果只读请求是在更新后的一两秒内发出的,则该屏幕的唯一版本。我知道这已经被讨论过here 和here。我知道问题是什么,但我想知道正确的解决方案可能是什么?这是一个我可以在哪里拥有陈旧数据的示例。
假设您构建了一个购物清单应用。
Entity 1: ShoppingList
Entity 2: ShoppingListItem
ShoppingList 实体上有一个字段,用于保存列表中项目的总金额。第二个实体是您的 ShoppingListItem。添加或删除 ShoppingListItem 时,需要更新 ShoppingList 上的总数。您有两种方法可以更新总数。
- 查询数据库并统计 ShoppingListItem 表中的商品数量。
- 在不计算数据库的情况下自动增加缓存的总计字段 +/- 1。
使用这两种解决方案,您最终都会得到陈旧的数据。 #1 可能已过时,因为添加/删除的原始保存可能尚未传播。因此查询将错过新记录。当您快速连续添加或删除多个项目时,#2 将具有陈旧的数据。保存 1 的总数已更新,但保存 2 时,保存 1 可能仍在传播,并且对保存 2 的 ShoppingList 总数的查询仍将反映保存 1 之前的原始状态。
所以我的问题是,解决此问题的正确方法是什么?在我看来,您有两个选择:
- 在使用缓存总计时,始终使用 memcached 实体。保存不会清除内存缓存,而是将更新后的实体直接注入回其中。这使 memcache 保持最新。这当然意味着未命中 memcache 的查询(例如获取所有 ShoppingList 实体的列表)可能仍会返回陈旧数据。但至少当所有的保存都完成时,数据库中缓存的总数是正确的。
- 处理这样一个事实,即您将拥有过时的数据,然后想办法在未来的某个时候清理它。要么安排一个 TaskQueue 重新查询 ShoppingList 并在 10-30 秒内更新总数,要么安排一个每 30 秒运行一次的 Cron 作业并查找所有已更新的 ShoppingList 实体。
我倾向于解决方案 #1。想法?
【问题讨论】: