Is UpdateOne thread safe?


I have multiple threads using UpdateOne inside a bulk write operation to update documents inside the database. I am trying to modify an item inside an array based on whether it exists or not and I also have an additional check inside the query parameter of UpdateOne which checks whether the added item is the latest or not based on the timestamp. For some reason, the update picks up the older timestamped item even though it receives the new timestamp item. My hypothesis is that, two updates happen at the same time, checks that the document does not contain the item inside the array and each of them overwrite on one another. This only happens for a very small number of times. My questions is, is there a way to make it thread safe such that if two updates happen at the same time, both of them happen serially, rather than in parallel? Is the query param and the aggregation pipeline param thread safe, do they happen in one lock step? If not, what can I do to mitigate this?

For ex: I have UpdateOne({id: ‘1234’, … additional condition to check if the item exists inside the array or not}, [{…aggregation pipeline to set the item inside the array which uses concatArray}]}

Let me know if you need additional clarifications.

Single updates are atomic, but you should also learn about Transactions in MongoDB

1 Like

Hi Jack,

Thank you for getting back. The thing that I am curious about is whether transaction will do the trick for me. Assuming I have two transactions trying to update the same document, the query condition in UpdateOne, how does it work? Will it check the database and see that a record does not exist and both of the transactions will update the same document hence a race condition since I have the condition to check whether a document exists or not is inside the query filter. Or will it happen in a serialized fashion, meaning transaction 1 will complete in one lock step followed by another transaction reading that value. Sorry for my lack of understanding here.

There is update and there is the upsert boolean option to an update.

An update of any sort is atomic. It may succeed or fail (e.g., if you update with upsert set to false and the document does not exist), but if it succeeds, no other action was performed on that document until the update was complete.

With multiple threads in your application, there is no way of telling what order the updates will happen, but you know that they didn’t write at the same time.

In many situations, there is no such thing as “just an update”, there’s more happening, so you want to wrap the steps in a transaction.

Check my answers in this post.

Two single doc update operation will not conflict with each other. If only one doc matches the filter condition and it is updated by the first update op, then second op will do nothing. in this case, they will happen sequentially.