thinky icon indicating copy to clipboard operation
thinky copied to clipboard

How to set consistency read_mode for query

Open ghost opened this issue 9 years ago • 16 comments

Hello, we have serious problems with concurrent data updates in table for one row and sub array of data. In rethink documentation there is a https://www.rethinkdb.com/docs/consistency/ where they say that we must change read_mode for each query, per example

r.table('users', {readMode: 'majority'}).filter({role: 'admin'}).run(conn, callback);

How can be set with Thinky.io ? There is an option in method for creating models

thinky.createModel(
    "table_name", 
    tableObjectWithFields, 
    {pk: "id"}
);

where the primary key is. Can we put read_mode: "majority" there also? Nothing in documentation can be found. Best regards

ghost avatar Feb 18 '16 20:02 ghost

+1

ramden avatar Feb 18 '16 21:02 ramden

Oh, I didn't know that you could pass the read mode in the table command. At the moment the only way to pass the read mode is to set it in run/execute.

It shouldn't too hard to add an option on a model.

neumino avatar Feb 19 '16 02:02 neumino

So please... Now we tested with r.table() and concurrent records are gone... it work as expected.

ghost avatar Feb 19 '16 09:02 ghost

You said: At the moment the only way to pass the read mode is to set it in run/execute.

Can we run like this:

Posts.filter({...}).run({readMode: "majority"}).then().error()

ghost avatar Feb 19 '16 09:02 ghost

I think it's possible only with callback, not like this above.

ghost avatar Feb 19 '16 14:02 ghost

Why do you think it's possible with only callback? As far as I know, it works with or without callbacks.

neumino avatar Feb 19 '16 15:02 neumino

I tested today, because all my code is based on run().then().error() promises and that doesn't work.

ghost avatar Feb 19 '16 15:02 ghost

What doesn't work?

neumino avatar Feb 19 '16 15:02 neumino

How do you test that it doesn't work

neumino avatar Feb 19 '16 15:02 neumino

I just tested it and it's working for me.

neumino avatar Feb 19 '16 15:02 neumino

After setting like above, we loosing our data in row. Imagine situation like this:

Table: items

{
   id: 21
   name: xxxxx
   comments: [
      { id: 1, name: ssss }, {id: 2, name: zzz}, ....
   ]
}

now, with 8 devices we sending update of the same item, but with different comments. At the end, instead of 8 comments total, we have only 1 (because of last device)... and this happening because devices sending data at the same time.

When we used r.table(), as I explained we have positive results, after sending item has 8 comments.

After adding readMode in run() this morning, all code works correctly, there is no errors, but we loosing comments again. Of course, adding comments one by one at the time is ok.

ghost avatar Feb 19 '16 15:02 ghost

First if you just append, you can never lose a comment as long as the write is successful since RethinkDB provide atomicity per document.

r.table('posts').get(21).update(function(post) {
  post.merge({
    comments: post('comments').append({id: xxx: name: yyy})
  })
})

Then readMode has to do with read, not write, so I'm not sure what your expectations are, but I'm pretty sure that readMode is passed to run. You can test it by bringing 3 servers, create one table with 3 replicas, kill 2, run a query with readMode outdated'/majority`.

Please provide your script that reproduces your issue.

neumino avatar Feb 19 '16 15:02 neumino

We using save() on model

Items.get(1).run()
    .then(function(item){
          item.comments.push(newComment)
          item.save()
              .then(function(savedItem){
                    // ....
              })
    })

ghost avatar Feb 19 '16 16:02 ghost

This is expected. What can happen is

server 1 get the item
server 2 get the same item
serve 1 write the document
server 2 overwrite the document

You can set any readMode you want, you can't prevent this case except if you have a global lock around your code (get/save). The query I wrote in https://github.com/neumino/thinky/issues/442#issuecomment-186276280 is what you want.

neumino avatar Feb 19 '16 16:02 neumino

Yes, exactly... when I changed code to r.table() with update() and append() problem is gone.

ghost avatar Feb 19 '16 16:02 ghost

Problem with readMode: single is when 3 clients reads and writes data with small time interval (ms). Client 2 reads data actually but replica is not finished yet. As they say, readMode: majority read always success written data.

ghost avatar Feb 19 '16 16:02 ghost