2

Hello I have the following JSON in database,

{
   recordName : String
   amount : Number
   approved : Boolean
}

Lets say I have two users issue these two command at the same time

Record.update({recordName: "test", approved: false},{$set: {amount : 5000, approved: false,...)

Record.update({recordName: "test", approved: false},{$set: {amount : 9999, approved: true,...)

Does it always guarantee that the final results will always be amount 9999 and approve true?

I am worried that the final result might sometimes be amount 5000 and approve is false.

I am not really sure about MongoDB pipeline.

I believe update is splitted into two stages? Find {recordName: "test", approved: false} then update? What if both query already found the entry, then it all depends on who updates first?

Zanko
  • 4,298
  • 4
  • 31
  • 54
  • Single document operations are always `atomic`, but the order of execution is not guaranteed. In your case, one of the queries would fail to update if they both update the `approved` status to 'true'. – BatScream Dec 23 '15 at 20:46
  • Or you could make use of document versioning techniques, take a look at this [question](http://stackoverflow.com/q/4185105/4207875) – saljuama Dec 23 '15 at 20:48
  • @BatScream I have read around with atomic and concurrency. It seems that mongodb will lock the process on write or update. So the question is. Is the update process refers to only when the document gets updated or it refer to the whole process of querying the data and then updating it? – Zanko Dec 23 '15 at 21:03

1 Answers1

1

Because single document updates are atomic, regardless of the order that your two commands execute, the document will end up as:

{amount : 9999, approved: true, ...}

If the first command executes first, then the second command will override it.

If the second command executes first, then the first command has no effect as approve is now true so the update conditions won't match.

What you're (correctly) doing is the well-established optimistic concurrency or "update if current" approach to managing concurrent access.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Hi. Thank you for answering! But something else is concerning me. I believe the "atomic" update is only referring to the update operation itself. Imagine the form is unapproved. Admin press approve and Worker press edit roughly the same time. Then Admin passed the query of approve = false. Worker also pass the query of approve = false. Now it is then up to who get the actual update first? The update operations above works if the pattern is like this Q1,U1, Q2, U2 or Q2, U2, Q1, U1 where Q is query and U is update. However it will not work if Q1, Q2, U1, U2. I hope I am making sense. – Zanko Dec 24 '15 at 05:31
  • No sir, the atomic nature of the update applies to both the condition check and the document modification together, as one atomic unit. – JohnnyHK Dec 24 '15 at 05:35
  • The reason I believe that query and update happened separately is because of this statement from mongoDB "If all update() operations complete the query portion before any client successfully inserts data, and there is no unique index on the name field, then each update operation may result in an insert." https://docs.mongodb.org/v3.0/reference/method/db.collection.update/ . If this is truly atomic then it is not possible that each result may result in an insert? – Zanko Dec 24 '15 at 05:36
  • That only applies to an `{upsert: true}` update which inserts a document, rather than atomically modifying an existing document. – JohnnyHK Dec 24 '15 at 05:43
  • Thank you so much for clarifying! I have spent 6 hours researching thinking that query and update is separated! – Zanko Dec 24 '15 at 05:47