postgresql 是 SELECT FOR UPDATE over multiple rows atomic?

postgresql is SELECT FOR UPDATE over multiple rows atomic?

假设有多个并行事务都执行相同的查询:

SELECT * FROM table1 FOR UPDATE;

这会导致死锁吗?

换句话说。上述语句中的操作 "lock all rows" 是原子操作还是在处理记录的过程中获取了锁?

是的,它会导致死锁。

这很容易证明。设置测试 table:

CREATE TABLE t AS SELECT i FROM generate_series(1,1000000) s(i);

... 然后 运行 这两个并行查询:

SELECT i FROM t ORDER BY i FOR UPDATE;
SELECT i FROM t ORDER BY i DESC FOR UPDATE;

您可以通过确保所有进程以相同顺序获取锁来防止死锁。或者,如果您想锁定 table 中的每条记录,您可以使用 table lock:

以原子方式执行此操作
LOCK t IN ROW SHARE MODE;