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 SHARE
或SELECT FOR KEY SHARE
这些行将被阻止,直到 当前交易结束;相反,SELECT FOR UPDATE
将 等待已运行任何这些命令的并发事务 在同一行上,然后将锁定并返回更新的行(或不 行,如果该行已被删除)。在REPEATABLE READ
或SERIALIZABLE
事务,但是如果一行会抛出错误 自事务开始后,待锁定已更改。为了更进一步的 讨论见第 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”的方式锁定单行?