如何选择更新如何适用于具有多行/结果的查询?

时间:2016-03-30 22:57:16

标签: sql postgresql

所以给出了这个交易:

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

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

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

因此,需要通过添加订单来维持订单的一致性来解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

documentation解释了发生的情况如下:

  

FOR UPDATE

     

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

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

文档中包含以下注释:

  

SELECT FOR UPDATE修改选定的行以将其标记为已锁定,等等   将导致磁盘写入。

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

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