我正在使用Gunicorn来托管一个Flask应用程序 - 它通过SQLAlchemy连接到数据库 - 在Nginx上。目前Gunicorn配置为总共使用5名工人。
简单地说,当按下按钮时,应用程序会检查数据库以确保该项目可用,以及是否将其提供给用户。
然而,当使用5名工作人员和Gunicorn时,如果两个用户同时按下按钮,则他们都被给予该项目。我把工人减少到1,这个问题就消失了。我该如何解决这个问题?
答案 0 :(得分:4)
这似乎是一个标准的并发控制问题,而不是Gunicorn的问题。
问题可能是你的“检查数据库”是这样实现的:
assign_item(第X项,用户U):
假设两个用户(A和B)尝试同时声明项目X,因此assign_item(X,A)在Worker#1上运行,assign_item(X,B)在Worker#2上运行。< / p>
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
找到更多信息