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:
- The first query determines the current amount.
- The second query is only fired if the amount is greater then the value to subtract and decrements the current amount.
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
amountis greater than 0: