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 锁
假设我有以下数据结构:
{ "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 锁