0

Let's suppose I am running the following command on multiple concurrent threads:

db.tasks.findAndModify({
    query: { status : "TODO" },
    update: { $set: { status : "DONE" } },
    new: true
})

From this command it's obvious that each document should be updated exactly once, since after the update the query no longer matches the state of the document. This implies that each running thread will get a different task on each execution.

Is this something that Mongo guarantees without the need for extra transactions? I've read similar questions about concurrency and document-level locking but none of them seems to be matching my case where the update operation modifies fields referenced on the query.

I am using Mongo 4.0 with WiredTiger storage engine if that's relevant.

Haris
  • 138
  • 1
  • 11
  • All write operations on a single document are atomic. Also, note that `findAndModify` updates the first matching document. – prasad_ May 20 '21 at 10:19

1 Answers1

0

As far as I can tell this isn't explicitly mentioned in the documentation.

However, https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/#upsert-with-unique-index says that findandmodify can insert multiple documents when invoked concurrently and an upsert is requested:

If all findOneAndUpdate() operations finish the query phase before any client successfully inserts data, and there is no unique index on the name field, each findOneAndUpdate() operation may result in an insert, creating multiple documents with name: Andy.

This suggests that the find part and the modify part are simply linearly sequenced, and there isn't anything special being done by f-a-m to ensure only one modification takes place for a given starting document.

But, the above could only apply to upserts.

D. SM
  • 13,584
  • 3
  • 12
  • 21