Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Your exemple of conditional update can be addressed using atomic update:

r.table('tv_shows') .filter({ name: 'Star Trek TNG' }) .update({ episodes: r('episodes').add(1) }) .run()

http://www.rethinkdb.com/docs/advanced-faq/#atomic



I think the atomicity model here works like a transaction on the whole document, where all the changes to the attributes of a document are updated all at once.

The scenario I described has to do with read-consistency, where the value read by a client should not be changed during the time of the read and the time of the update. The usual way of handling it was to take a write lock for the duration to prevent update from others but that degrades concurrency. The other way is to do optimistic lock (or conditional update) to allow the client to detect change during the time and retry with the new value.


My point was that you don't have to do that with rethink because the entire query gets executed on the server. You don't have to take the value down to the client, make the change, and then send it back. The entire update gets evaluated on the server and the server handles atomicity in various ways (depending on the query).


That approach would only work if all the logic to compute the update can be expressed in the update query. It will break down if the read-eval-update cycle involves the client. There are many scenarios involved the clients.

E.g. the client reads a value, displays to the user, gets input from the user which is based on the old value, and stores the updated value. If another user doing the same thing has already changed it, the client would like to know that and let the user retry, with the new current value.


I think you, ww520, have a very well point here and I'm also interesten in what RethinkDB can offer for this very usage scenario. From what I read from the ReQL command reference there it should be possible to do something like:

  r.table('foo').get(5).update({ 'bar': r.branch(r['baz'] == 0, "foo", r.error("invalid baz!"))})
have not tested it, but this is how I understand it...


Do you think something like the following should work with RethinkDB?

  r.table('foo')
   .get(5)
   .update({
     '_rev': r.branch(r['_rev'] == 5,
       r('_rev').add(1),
       r.error("invalid revision")
     ),
     'name': "awesome name"
   })
the basic idea is that `name` should be update to "awesome name" and `_rev` should be incremented by 1, but only if `_rev` is 5, otherwise an "invalid revision" error should be thrown.


That would work. I didn't realize you can raise error on the row. Good work!


Yes, this will work.


awesome, thanks!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: