【问题标题】:Gunicorn, Flask and SQLAlchemy: Concurrent RequestsGunicorn、Flask 和 SQLAlchemy:并发请求
【发布时间】:2013-01-07 20:26:47
【问题描述】:

我正在使用 Gunicorn 在 Nginx 上托管一个 Flask 应用程序 - 它通过 SQLAlchemy 连接到数据库。目前 Gunicorn 配置为总共使用 5 个工人。

简单地说,当按下按钮时,应用程序会检查数据库以确保该项目可用,如果可用,则将其提供给用户。

但是,当使用 5 个工人和 Gunicorn 时,如果两个用户同时按下按钮,他们都会获得该物品。我将工人减少到 1,这个问题就消失了。我该如何解决这个问题?

【问题讨论】:

    标签: gunicorn


    【解决方案1】:

    这似乎是标准的并发控制问题,而不是 Gunicorn 的问题。

    问题可能是您的“检查数据库”是这样实现的:

    assign_item(项目 X,用户 U):

    1. 检查项目 X 在一个查询中是否可用
    2. 将项目 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找到

    【讨论】:

    • 我不明白原子操作如何解决这个问题。第二个 SELECT 仍将返回 True。我相信解决问题的一种方法是在 SELECT 语句中使用 FOR UPDATE。
    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 2017-12-27
    • 2017-12-20
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多