我有这样的查询:
UPDATE table1 SET
col = 'some value'
WHERE id = X
RETURNING col1, (SELECT col2 FROM table2 WHERE id = table1.table2_id FOR UPDATE);
因此,此查询将锁定两个表,table1
和table2
,对吧?但是哪一个会被锁定?
答案 0 :(得分: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
个锁:
这些表格全部锁定在InitPlan
的{{1}}中,在我看来execMain.c
将再次锁定table1
。