I have just traced down an annoying bug which is basicly a race condition. For the sake of the argument lets assume a very simple document structure like { _id : 'XXX', amount : 100 }.
Hundreds of these these documents exist inside a collection and are accessed by multiple writers which effectively try to lower the amount by any value but never below 0. Currently this is done with two queries:
This is of course prone to result in a mess when multiple threads do this simultaneously. But is there a way to do this in an atomic operation? I couldn't find anything like a test-and-set operation in the docs.
If its relevant: The code running these operations is serverside JavaScript running with multiple Node.js instances and the mongodb npm package.
Qualify the update to only update the doc if amount is greater than 0:
db.coll.update({_id: 'XXX', amount: {$gt: 0}}, {$inc: {amount: -1}})