【问题标题】:Select for Update behavior选择更新行为
【发布时间】:2015-06-28 07:34:23
【问题描述】:

我非常了解当使用 SELECT FOR UPDATE 并发生另一个 SELECT/UPDATE 时更新一行会发生什么。但是当使用 SELECT FOR UPDATE 发生两个请求时会发生什么。

例如:

  1. 线程 A 启动一个事务并在一行上执行 SELECT FOR UPDATE 并检索一些信息并开始一个需要时间的 HTTP 请求。调用返回后事务提交并关闭会话。
  2. 线程 B,当 A 等待请求时,启动一个新事务并在同一行上执行 SELECT FOR UPDATE。它会检索信息并继续执行 HTTP 请求,还是会等待线程 A 提交/执行更新,然后从行中检索数据。

我不在乎一旦请求返回和更新表的时间到来时会发生什么。用于更新的第二个将抛出或更新行上最后可能的数据。

但是实际的 HTTP 请求会由他们俩完成吗?换句话说,在这种情况下 SELECT FOR UPDATE 可以用作(滥用)线程同步机制吗?

【问题讨论】:

    标签: multithreading postgresql concurrency thread-safety select-for-update


    【解决方案1】:

    您正在混淆图层。 PostgreSQL 不做 HTTP。 SELECT ... FOR UPDATE 与 HTTP 无关。

    它是这样工作的:

    • 会话 1 执行 BEGIN
    • 会话 2 执行 BEGIN
    • 会话 1 执行 SELECT ... FOR UPDATE 并获得一行或多行
    • 会话 2 执行 SELECT ... FOR UPDATE 并匹配同一行之一,因此它阻塞,不返回任何内容,直到...
    • 会话 1 执行 COMMIT 或 ROLLBACK
    • 会话 2 从之前的 SELECT ... FOR UPDATE 获取结果

    换句话说,锁定持续时间由事务边界控制。事务边界的位置取决于您的应用程序和框架,位于您尚未以任何方式识别的数据库层之上。

    (另外,这与线程无关)。

    【讨论】:

    • 谢谢克雷格。是的,我知道线程和 Http 与 PostgreSQL 无关。也许我没有正确表达自己。但是,我认为您回答了我的问题。会话 2 阻止其执行并且在会话 1 提交之前不会继续。因此,在会话 1 提交更改之前,它不会前进到 SELECT FOR UPDATE 之后存在的 HTTP 调用。我说的对吗?
    • @idipous 正如我所说,无法回答这个问题,因为我不知道您使用的是什么框架,它如何管理事务等。这取决于应用程序何时提交。就这些。所以你必须弄清楚应用程序何时提交。听起来,根据您的编辑,事务在与客户端的 HTTP 交换期间保持打开状态,在这种情况下,是的,它将阻止会话 B 继续,直到会话 A 返回。这完全取决于您何时提交。
    • 我编辑了我的问题以清除事务开始和提交点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多