Rethinkdb atomic retrieve and update

和自甴很熟 提交于 2019-12-12 04:56:50

问题


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}

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.

Is this possible with rethinkdb ?


回答1:


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

You can do something like this:

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

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.

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.



来源:https://stackoverflow.com/questions/29368121/rethinkdb-atomic-retrieve-and-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!