我正在使用 Gunicorn 在 Nginx 上托管一个 Flask 应用程序——它通过 SQLAlchemy 连接到数据库。目前 Gunicorn 配置为总共使用 5 个工人。
简而言之,当按下按钮时,应用程序会检查数据库以确保该项目可用,如果可用,则将其提供给用户。
但是,当使用 Gunicorn 使用 5 名工人时,如果两个用户同时按下按钮,他们都会获得该物品。我将工人减少到 1,这个问题就消失了。我该如何解决这个问题?
我正在使用 Gunicorn 在 Nginx 上托管一个 Flask 应用程序——它通过 SQLAlchemy 连接到数据库。目前 Gunicorn 配置为总共使用 5 个工人。
简而言之,当按下按钮时,应用程序会检查数据库以确保该项目可用,如果可用,则将其提供给用户。
但是,当使用 Gunicorn 使用 5 名工人时,如果两个用户同时按下按钮,他们都会获得该物品。我将工人减少到 1,这个问题就消失了。我该如何解决这个问题?
这似乎是一个标准的并发控制问题,而不是 Gunicorn 的问题。
问题可能是您的“检查数据库”是这样实现的:
assign_item(项目 X,用户 U):
假设两个用户(A 和 B)试图同时认领项目 X,因此 assign_item(X, A) 在 Worker #1 上运行,assign_item(X, B) 在 Worker #2 上运行。
Worker #1 可以运行 assign_item(X, A) 的第一行,然后 Worker #2 运行 assign_item(X, B) 的第一行。此时,两个检查都返回 True;该项目可用。因此,现在两个工作人员都运行各自的下一个操作,并将相同的项目返回给用户。
使用数据库解决这个问题的方法是在 assign_item 中使用 BEGIN TRANSACTION 和 END TRANSACTION,确保这两个操作原子发生。
这是一个众所周知的问题,可以在http://en.wikipedia.org/wiki/Concurrency_control找到更多信息