在更新时锁定一个表,在子查询中锁定另一个表,哪一个将首先被锁定?

问题描述 投票:1回答:1

我有这样的查询:

UPDATE table1 SET 
col = 'some value' 
WHERE id = X
RETURNING col1, (SELECT col2 FROM table2 WHERE id = table1.table2_id FOR UPDATE);

所以,这个查询会锁定两个表,table1table2,对吧?但哪一个会被锁定?

postgresql postgresql-9.6
1个回答
1
投票

查询的执行计划可能如下所示:

                                        QUERY PLAN                                         
-------------------------------------------------------------------------------------------
 Update on laurenz.table1
   Output: table1.col1, (SubPlan 1)
   ->  Index Scan using table1_pkey on laurenz.table1
         Output: table1.id, table1.table2_id, 'some value'::text, table1.col1, table1.ctid
         Index Cond: (table1.id = 42)
   SubPlan 1
     ->  LockRows
           Output: table2.col2, table2.ctid
           ->  Index Scan using table2_pkey on laurenz.table2
                 Output: table2.col2, table2.ctid
                 Index Cond: (table2.id = table1.table2_id)

这表明table1中的行首先被锁定。

查看代码,我看到ExecUpdate首先调用EvalPlanQual,其中更新的元组被锁定,并且仅在调用ExecProcessReturning处理RETURNING子句之后。

所以是的,table1中的行首先被锁定。

到目前为止,我已经处理了行锁,但是表上还有ROW EXCLUSIVE锁:

这些表都被锁定在InitPlanexecMain.c中,在我看来,table1将再次锁定在table2之前。

© www.soinside.com 2019 - 2024. All rights reserved.