Take the 2-minute tour ×

I am using Gunicorn to host a Flask app - which connects to the DB via SQLAlchemy - on Nginx. Currently Gunicorn is configured to use 5 workers in total.

Put simply, when a button is pressed, the application checks the DB to make sure that the item is available and if it is gives it to the user.

However, when using 5 workers with Gunicorn, if two users press the button simultaneously they are both given the item. I reduced the workers to 1 and this issue went away. How do I go about solving this issue?

share|improve this question
add comment

1 Answer

This seems like a standard concurrency control issue rather than an issue with Gunicorn.

The problem is probably that your "checking the DB" is implemented like this:

assign_item(Item X, User U):

  1. Check that item X is available in one query
  2. Assign item X to user U and return that value.

Suppose two users (A and B) try to claim item X at the same time, so assign_item(X, A) is run on Worker #1 and assign_item(X, B) is run on the Worker #2.

It is possible for Worker #1 to run the first line of assign_item(X, A), then for Worker #2 to run the first line of assign_item(X, B). At this point, both checks returned True; the item is available. So now both workers run their respective next operations and both return the same item to the users.

The way to solve this using a database is to use BEGIN TRANSACTION and END TRANSACTION in assign_item, ensuring that the two operations happen atomically.

This is a well known problem, further information can be found at http://en.wikipedia.org/wiki/Concurrency_control

share|improve this answer
add comment

Your Answer


