Recommended way to handle write conflicts inside transactions?

Hello, after adding transaction support, I noticed a lot of write conflicts since my app does a lot of concurrent updates on the same document.

This is by design, as it’s a chat application and multiple users can, for example, update a “group chat” at the same time by writing a lot of messages concurrently.

Is there some way to avoid write conflicts by telling Mongo to queue operations and wait for the write lock to be released instead of throwing a write conflict exception? Or how would you handle these issues?

2 Likes

Welcome to the MongoDB Community @stefan_fai,

It ls always hard to predict outcomes without seeing actual code. What I can say is that concurrent writes to any single document were and are atomic even before we announced support for ACID transactions. So you can just fire those writes at the single doc for the chat and have them update just fine.

Thanks for the reply, it’s true that before introducing transactions, concurrent updates on the same document worked without problems, however it looks like I’m running into the following issue:

https://docs.mongodb.com/manual/core/transactions-production-consideration/#in-progress-transactions-and-write-conflicts.

If a transaction is in progress and a write outside the transaction modifies a document that an operation in the transaction later tries to modify, the transaction aborts because of a write conflict

I’m not sure how to handle this case, since I might have dozens of concurrent transactions writing to the same document.

This is an example that produces write conflicts if run in parallel:

Query query = new Query();
query.addCriteria(Criteria.where("conversationId").is(conversation.getId()));
query.addCriteria(Criteria.where("ownerId").is(receiver.getId()));

Update update = new Update();
update.inc("unreadCount", 1);

mongoTemplate.updateFirst(query, update, Contact.class);
1 Like

Just remove the transaction and let the database resolve the writes in the order they come in? Transactions really come into their own when updates must be atomic across multiple documents. In that case without a transaction the updates to two documents may not be atomic without a transaction.

That was just a snippet of my code, I actually do update multiple documents in different collections as part of the transaction… I guess I’ll need to remove the transaction anyway?

If the transaction is required you should leave it in. Then if their are write-conflicts you will have to retry.