Locking Documents In Mongo

I would like to know if we can lock the documents in Mongo. We have a .NET service which has 3 different instances of itself. It looks into a collection and gets the document from Mongo.

What we want is, if the first instance of the service gets the Document-1 from the collection, then the second instance should not be able to get the same document (Document-1) as it is being processed by another instance. The second instance should get next available document (e.g Document-2). Same with third instance, it should not be able to find the Document-1 or Document-2. It should pick Document-3. But if the first document is not processed correctly, then the lock from that document should be released and the next available service instance should pick it up.

Please help. Thank you.

Hi @Jason_Widener,

In MongoDB we recommend using the findAndModify command for this scenario.

This command is atomic and thus lock the document for a status change.

Each service instance should do:

db.coll.findAndModify({id : "doc1", status : "pending"},{$set : { status : "processing"}});

This way only one service only will see the pending document.

If the processing fails you can change the status back to pending and sort by creation datefor another service to pick it up.

If there is a more complex logic consider using transactions.

Please let me know if you have any questions.

Best regards
Pavel

2 Likes

Hello Pavel,

Thank you so much for your reply. It is really helpful. Just one more question, let say we use findAndModify and update the status to “Processing” when a service picks up the document. And after some time, the service gets stuck for some time and does not respond anything (not error and also not successful). So in case if the document is in “processing” status for more then 15 min, we want to change the status to “Available” so that next time service runs, document can be picked again. Is it possible to do in Mongo ?

Thank you,
Jason

Hi @Jason_Widener,

We can only offer a TTL partial index on status : “processing” with 15 min time to live however, it will only remove the document.

Then you can consider listen to those deletes via a changestream or an Atlas trigger (if this is running on MongoDB Atlas cluster) and recreate the record.

However, this might be challenging and not really error proof.

I will suggest 2 approaches:

  1. Have a timeout in your code that after the allowed timeout will throw an error and in the catch block will update the status back to “pending”.
  2. Have a logic to pull the data of running processes for more than 15min and automatically change their statuses.

Best regards,
Pavel

1 Like

Awesome. thank you so much for your help.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.