Rethinkdb 原子检索和更新

Rethinkdb atomic retrieve and update

假设我有以下数据结构:

{ "name": "i1", "time": 1, "status": 1}
{ "name": "i2", "time": 2, "status": 1}
{ "name": "i3", "time": 3, "status": 1}
{ "name": "i4", "time": 4, "status": 2}

我需要检索时间最长且 "status" = 1 的项目。然后将它的 "status" 更新为 2,所有这些都是自动进行的,因此其他项目无法检索到相同的项目同时消费者。

rethinkdb 可以吗?

由于 RethinkDB 中的原子性仅在每个文档级别得到保证,因此这只是部分可能。

你可以这样做:

r.table(...)
  .orderBy(index=r.desc("time"))
  .filter({status: 1})
  .limit(1)
  .update(r.branch(r.row["status"] == 1, {status: 2}, {}), return_changes=True)

update 中的所有内容都将自动应用。因此,如果另一个客户端已将条目的状态设置为 2,则查询将 return {unchanged: 1} 并且您可以再次 运行 直到它成功执行更新。

但不保证更新完成时,选中的文档仍然是时间最长的文档。另一个客户端可以在该查询 运行ning 时插入一个具有更长时间的新文档,这将使查询将当时唯一的第二大文档的状态更新为 2.

为了完全防止这种情况发生,您需要为 table.

使用显式互斥锁或 read/write 锁