【问题标题】:Concurrent updates with psycopg2与 psycopg2 并发更新
【发布时间】:2022-01-21 18:55:12
【问题描述】:

在服务器上,我有一个由一个或多个客户端调用的 API。服务器几乎可以同时接收同一 PostgreSQL 属性的多个更新指令。这些请求不会在完全相同的时间到达,我只想一个接一个地执行它们。由于 (Flask) API,我无法控制之前的调用结束,因此可以在之前的更新完成之前调用新的更新。除了 psycopg2/postgresql 之外,我希望能够将更新排队并一个接一个地安静地进行(甚至可能不按顺序),但它似乎不是那样工作的。

以下是需要更新时在服务器上调用的函数的简化版本。如果重要的话,要更新的属性是一个 JSONB 对象。因此,有“路径”来确定要更新 JSONB 对象的哪一部分。所以 API 调用如下所示:

def pg_update(data, path):
    conn = psycopg2.connect(...) # always the same database.
    cur = conn.cursor()

    # JSONB update for a single selected row and column.
    # 'column' and 'select_row' are determined with the parameters 'data' and 'path'.
    command = (
        f"""UPDATE MY_TABLE SET """
        f"""{column} = jsonb_merge({column}, %s) """
        f"""WHERE {select_row};"""
    )

    cur.execute(command, [Json(data)])
    conn.commit()

当连续调用两次时,此调用会导致错误(在“cur.execute”处):

psycopg2.errors.InternalError_: tuple concurrently updated

由于服务器一直在运行,我还可以在 API 调用“pg_update”之外定义conn,以便使用相同的 psycopg2 连接处理所有调用。但是,当为同一个属性请求两个更新时,我得到了:

psycopg2.ProgrammingError: execute cannot be used while an asynchronous query is underway

我将async_ = False 强制输入psycopg2.connect,以防万一。没有变化。

总而言之,我怎样才能允许对相同属性进行多次更新,一个接一个,即使这些更新几乎同时来自独立的、不可控的客户端请求?也许需要一个锁定机制?排队机制?

【问题讨论】:

    标签: python postgresql psycopg2


    【解决方案1】:

    您可以使用SELECT FOR UPDATE 机制。 Here 是一些简单的例子,可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-18
      • 2021-05-20
      • 2021-02-28
      • 2021-09-23
      • 2011-11-23
      • 2016-05-13
      • 1970-01-01
      相关资源
      最近更新 更多