vadimdemedes / mongorito

🍹 MongoDB ODM for Node.js apps based on Redux
1.38k stars 90 forks source link

How to achieve Concurrency Control? #177

Open zixinw opened 7 years ago

zixinw commented 7 years ago

I am facing a high concurrency problem, and I found https://docs.mongodb.com/v3.0/core/write-operations-atomicity/. Is there anything like that ?

vadimdemedes commented 7 years ago

So you would like to use $isolated? You can extend Mongorito to pass $isolated on every update operation. Check Writing Plugins section in readme.

zixinw commented 7 years ago

Actually, I want is:

    let test = new Test()
    yield test.save()

    let test1 = yield Test.findById(test.get('_id'))
    let test2 = yield Test.findById(test.get('_id'))

    //make some modifications to test1 and  test2

    yield test1.save()
    yield test2.save() //should  throw Exception, because the document has been modified, some fields may have been changed, Storing test2 will overwrite those fileds.

See this: https://docs.mongodb.com/v3.0/tutorial/update-if-current/

My mongorito version is 2.2.0

vadimdemedes commented 7 years ago

How would you implement this kind of behavior?

zixinw commented 7 years ago

It's a example I means, but the callbacks actually work like that. Perhaps I can maintain a field version, and increase it each time when the native mongodb update is called. But it seems impossible to achieve in Mongorito, here is the source code. image

The update query condition has only _id, adding version here I think it would work.

niallobrien commented 7 years ago

Interesting problem. Any solution for this yet?

vadimdemedes commented 7 years ago

I still don't understand the problem completely. @wangzixin1113 Initially you wanted to use $isolated and in the last screenshot and link you point to atomic operations like $inc and $set. Could you provide more information? Maybe examples of the problem/solution in other libraries, like mongoose?

zaaack commented 7 years ago

I think this is a expansibility problem since upgrading to v3, just like the problem I'm facing. We cannot easily override any built-in behavior because internal action and middleware cannot be override. If I want to change update, I cann't override it with a custom action, because other plugins might depend on it.

vadimdemedes commented 7 years ago

We cannot easily override any built-in behavior because internal action and middleware cannot be override.

@zaaack You can override any internal actions in this way:

const ActionTypes = require('mongorito');

const myMiddleware = () => ({dispatch, getState}) => next => action => {
  if (action.type !== UPDATE) {
    // pass through any other action
    return next(action);
  }

  // action.type is UPDATE, start customization of the action props
  return next(action);
};