2

因此,鉴于此交易:

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

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

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

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

4

1 回答 1

3

文档解释了发生的情况如下:

更新

FOR UPDATE导致SELECT语句检索到的行被锁定,就像更新一样。这可以防止它们被其他事务锁定、修改或删除,直到当前事务结束。也就是说,其他尝试UPDATE, DELETE, SELECT FOR UPDATE, 或这些行的事务将被阻塞SELECT FOR NO KEY UPDATE,直到当前事务结束;相反,将等待已在同一行上运行任何这些命令的并发事务,然后将锁定并返回更新的行(或没有行,如果该行已被删除)。但是,在or 事务中,如果要锁定的行在事务开始后发生了更改,则会引发错误。有关进一步的讨论,请参见第 13.4 节。SELECT FOR SHARESELECT FOR KEY SHARESELECT FOR UPDATEREPEATABLE READSERIALIZABLE

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

该文档包括此说明:

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

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

基于此,我认为使用SELECT FOR UPDATE.

于 2016-03-30T23:07:47.843 回答