findAndModify()
Quick question – on findAndModify() concurrency.
Ex: 2 threads are trying to pull the same document at the same time (using status=pending), and assuming 1st thread gets the lock on the doc and change the status to “in-process” through findAndModify().
The 2nd thread will have to wait till the 1st thready is done and will never return that particular doc as the status has been changed to “in-process” by the 1st thread.
Just want to make sure my understanding of this behavior of “findAndModify()” is correct as this will impact one of the application design.
Answer :
In the scenario you are describing, there wouldn’t be any more guarantee (than for standard update operations) that the document couldn’t be updated by both threads.
Hence the 2nd thread could still be fetching the same document and updating it accordingly.
That is, of course, if the two findAndModify fetched the document at the same time and not if the second
findAndModify happens when the first has completed and the updated data has already been consolidated.
http://www.askasya.com/post/findandmodify/
Above article describes how findAndModify works, highlights its differences with a standard update operation and talks about application patterns where the findAndModify can be useful.
So essentially findAndModify() will not guarantee serializing concurrent requests.
Lets take this example:
T0 – Thread 1 and Thread 2 both issue findAndModify() with query of “status=Pending”. They both can now find Doc1 which satisfies the condition.
T1 – Thread 1 acquires the lock on Doc1 and changes the status to “In-Process”. At this point Thread 2 is waiting for Thread 1 to release the write lock.
T2 – Thread 1 returns (with new:false) allowing Thread 2 to get the start its processing.
Thread 2 will NOT recheck for the original criteria (status=pending) and hence go ahead and update the same document even though the new status modified by thread 1 does not match the criteria.
It will also update the document with “in-process” and return with old document (new:false).
Now the question is: what is the status that Thread 1 and Thread 2 see after they get the returned document?
Will both threads see “Pending”, or Thread 1 will see “Pending” and Thread 2 will see “In-process” ?
If can guarantee that Thread 1 sees “Pending” and Thread 2 see “In-Process”, we are fine as we can discard the one from thread 2.
However if we cannot guarantee this, and both threads could see “Pending”, then there is no way we can discard processing from any of the threads.
Basically the question is – how do we guarantee only 1 thread can process the document ?