Rethinkdb 原子检索和更新 [英] Rethinkdb atomic retrieve and update

查看:43
本文介绍了Rethinkdb 原子检索和更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下数据结构:

Say I have the following data structure:

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

我需要检索时间最长且状态"= 1的项目.然后将其状态"更新为2,所有这些都是原子的,因此其他消费者无法同时检索相同的项目.

I need to retrieve the item with the largest time and "status" = 1. Then update it's "status" to 2, all this atomically, so the same item can't be retrieved by other consumer in the same time.

这可以通过 rethinkdb 实现吗?

Is this possible with rethinkdb ?

推荐答案

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

Since atomicity in RethinkDB is only guaranteed on a per-document level, this is only partially possible.

你可以这样做:

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,查询将返回 {unchanged: 1},您可以再次运行它,直到它成功执行更新.

Everything inside of the update is going to be applied atomically. So in case the status of the entry has already been set to 2 by another client, the query will return {unchanged: 1} and you can run it again until it successfully performs an update.

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

However it does not guarantee that at the time where the update is done, the selected document is still the one with the largest time. Another client could insert a new document with a larger time while this query was running, which would make the query update the status of the then only second largest document to 2.

为了完全防止这种情况,您需要为表使用显式互斥锁或读/写锁.

For fully protecting against this, you'd need to use an explicit mutex or read/write lock for the table.

这篇关于Rethinkdb 原子检索和更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆