Search code examples
pythonmongodbflaskmongoengine

Prevent MongoDB race condition in update query during multiple requests


I have a simple web application in Flask and I use Mongoengine as ORM. The API takes in a request, adds the request to a worker queue, decreases the user's license count and save it back. Example code given below:

def process_request(body):
    user = User.objects.get(username=username_from_session)

    add_request_to_worker_queue(body['data'])
    
    user.total_license_count = user.total_license_count - 1

    user.save()

This works as expected. But I noticed when multiple requests are sent from the same user at the same time, the license_count is not decreased as expected. I suppose this is because the other requests do not see the update of the first request as it is still processing.

I tried adding a random delay to the requests but it did not help. I don't know if there is some form of lock mechanism in MongoDB to wait till the other process finishes processing. How do I fix this to prevent this from happening.

My stack is Python, Flask, Mongoengine, MongoDB


Solution

  • Use conditional updates, set condition as license_count > 0, use $inc operator to perform the decrement and read the number of updates done to see if the count started out positive.