select for update 如何适用于具有多行/结果的查询?

Posted

技术标签:

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

所以考虑到这笔交易:

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

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

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

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

【问题讨论】:

【参考方案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可能会出现死锁情况。

【讨论】:

以上是关于select for update 如何适用于具有多行/结果的查询?的主要内容,如果未能解决你的问题,请参考以下文章

数据库:Mysql中“select ... for update”排他锁分析

数据库:Mysql中“select ... for update”排他锁分析

MySQL 查询适用于 SELECT 但不适用于 UPDATE 语句

数据库:Mysql中“select ... for update”排他锁分析

在 SQL Server 中,如何以类似于 Oracle 的“SELECT FOR UPDATE WAIT”的方式锁定单行?

声明“for update”如何工作?