1

i know, there is no transaction support on mongo DB. But now i need to read an value of an document, increment by 1 and write the new value.

Or - different way: Update an element and read the value at the same time. For this i like to use find and modify : http://www.mongodb.org/display/DOCS/findAndModify+Command

this command updates an document and returns the value before updating. Is this happens in on (same like) transaction? The point is: is it possible that an other session updates the same value between the two steps of the other session?

(sorry, for me it's hard to explain - i hope you understand what i'm trying to say)

thank you.

Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
The Bndr
  • 13,204
  • 16
  • 68
  • 107
  • If you just need to perform the increment without needing the full document, use an `update` with the `$inc` atomic modifier. – JohnnyHK Jul 04 '12 at 15:38
  • @JohnnyHK only update isn't enough, because i need the (new, incremented) value to process this value on application side – The Bndr Jul 05 '12 at 05:57

2 Answers2

5

findAndModify command is atomic. Which means that no other operation can happen between find and modify parts. This command was made exactly for things like incrementing counters/settings flags and reading them at the same time.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • 1
    be careful though, due its nature, findAndModify does not yield and so you end up taking out a lock for a long time if you write inefficient queries with that particular command. – Adam Comerford Jul 04 '12 at 16:46
  • @Sergio Tulentsev thank you. did you guess (conjecture) this? Or maybe you find this somewhere at the mongoDB documentation? //Edit: is there a way, to find after modify? In order to receive the incremented value? Because findAndModify returns the value before inctementing – The Bndr Jul 05 '12 at 06:31
  • You can pass a `new` flag, it will make the command return the document after update. See [the docs](http://www.mongodb.org/display/DOCS/findAndModify+Command). As for the atomicity, there were discussions in the google group about this. – Sergio Tulentsev Jul 05 '12 at 06:48
  • @ Sergio Tulentsev the new flag.. i found this at documentation at the same time you are writing this answer! ;-) That works! Thank you. – The Bndr Jul 05 '12 at 06:52
1

I still doubt about the atomicity.

Under "Upsert and Unique Index¶" Section here http://docs.mongodb.org/manual/reference/command/findAndModify/

It is written that multiple clients can perform query operation simultaneously, and then they will perform update operation.

When the findAndModify command includes the upsert: true option and the query field(s) is not uniquely indexed, the command could insert a document multiple times in certain circumstances.

If all the commands finish the query phase before any command starts the modify phase, and there is no unique index on the name field, the commands may each perform an upsert, creating multiple duplicate documents.

If it would have been atomic then it should assume a read write lock for time being thus preventing other connections from performing "query phase".

Is it a case with only upsert flag ? Since it creates a new document, may be it would be okay when a document match is found and it behaves Atomic in nature in that case. Can someone please clarify ?

Ritvick
  • 78
  • 6
  • In that case, don't use upsert. Get inbetween the query and modify phases by trying an insert first that should fail on conflict in a unique index, then if it fails do an update. –  Jun 05 '16 at 22:24
  • Yes, you are correct. It's _not_ atomic. In nodejs, with multiple writers in different processes / threads, I can easily trigger a duplicate. – forivall Jun 14 '23 at 04:32