【问题标题】:How select for update works for queries with multiple rows/results?select for update 如何适用于具有多行/结果的查询?
【发布时间】:2016-07-19 04:29:08
【问题描述】:

所以考虑到这笔交易:

select * from table_a where field_a = 'A' for update;

假设这给出了多行/结果,数据库会立即锁定所有结果吗?还是一次将其锁定一排。

如果后者为真,这是否意味着同时运行此查询会导致死锁?

那么,需要添加一个order by来保持订单的一致性来解决这个问题吗?

【问题讨论】:

    标签: sql postgresql select-for-update


    【解决方案1】:

    documentation 解释如下发生的事情:

    更新

    FOR UPDATE 使SELECT 语句检索到的行变为 像更新一样被锁定。这可以防止它们被锁定, 被其他事务修改或删除,直到当前 交易结束。也就是其他尝试UPDATE的事务, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARESELECT FOR KEY SHARE 这些行将被阻止,直到 当前交易结束;相反,SELECT FOR UPDATE 将 等待已运行任何这些命令的并发事务 在同一行上,然后将锁定并返回更新的行(或不 行,如果该行已被删除)。在REPEATABLE READSERIALIZABLE事务,但是如果一行会抛出错误 自事务开始后,待锁定已更改。为了更进一步的 讨论见第 13.4 节。

    您的问题的直接答案是 Postgres 不能“立即”锁定所有行;它必须首先找到它们。请记住,这是行级锁定而不是表级锁定。

    文档包括此注释:

    SELECT FOR UPDATE 修改选定的行以将它们标记为锁定,因此 将导致磁盘写入。

    我将其解释为 Postgres 执行 SELECT 查询并在找到行时将它们标记为已锁定。当 Postgres 识别该行时,锁(对于给定的行)开始。它一直持续到交易结束。

    基于此,我认为使用SELECT FOR UPDATE可能会出现死锁情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 2020-04-04
      相关资源
      最近更新 更多