有没有ORDER BY
在SQL UPDATE
命令。Postgres以任意顺序更新行:
为了绝对避免死锁,您可以在可序列化事务隔离中运行语句。但这更昂贵,您需要准备在序列化失败时重复命令。
最好的做法可能是SELECT ... ORDER BY ... FOR UPDATE
在子查询中显式锁定,或者SELECT
在事务中独立使用-默认为“读取已提交”隔离级别。在pgsql-general上引用Tom Lane:
应该没问题--- FOR UPDATE锁定始终是SELECT管道中的最后一步。
这应该做的工作:
BEGIN;
SELECT 1
FROM foo
WHERE baz = 1234
ORDER BY bar
FOR UPDATE;
UPDATE foo
SET bar = bar + 1
WHERE baz = 1234;
COMMIT;
上的多列索引(baz, bar)
可能是性能的理想选择。但是由于bar
显然已更新很多,因此单列索引(baz)
可能更好。取决于几个因素。每行多少行baz
?没有多列索引,是否可以进行HOT更新?...
如果 baz
同时更新,则冲突的可能性极小(根据文档):
SELECT
命令可能在READ COMMITTED
事务隔离级别运行,并使用ORDER BY
和锁定子句可能会无序返回行。...
另外,如果您应具有涉及的唯一约束bar
,请考虑DEFERRABLE
在同一命令中避免唯一冲突的约束。相关答案:
CREATE TABLE
代码。