说我有以下数据结构:
{ "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的项目。然后将其“状态”更新为2,所有这些原子化,因此同一项目不能被其他消费者同时检索。
这可以用rethinkdb吗?
答案 0 :(得分:1)
由于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,则查询将返回{未更改:1},您可以再次运行它,直到它成功执行更新。
但是,并不保证在完成更新时,所选文档仍然是具有最长时间的文档。另一个客户端可以在运行此查询时插入一个具有更长时间的新文档,这将使查询将当时仅次于第二大的文档的状态更新为2.
为了完全防范这种情况,您需要对表使用显式互斥锁或读/写锁。