我的同事在工作,我想知道在更新期间,如果在where
子句中使用相同列时正在更新列,则可能会出现死锁。
例如:
UPDATE EMPLOYEES
SET DEPT_ID = NULL
WHERE DEPT_ID = 13;
因此,如果表EMPLOYEES
包含大约一百万条记录,是否有可能出现死锁?
答案 0 :(得分:0)
根本没有机会 。在Postgres中,单个查询不仅永远不会死锁(请参阅注释),在并发事务中也不存在与同一查询结合的死锁的可能性。
死锁的最低“要求”:
理论上两个并发,如果有多个行具有相同的DEPT_IT
,则显示的相同调用可能会出现死锁。由于ORDER BY
没有DELETE
,因此可以对行进行排他行锁定以任意顺序删除。两个相同的命令可能以不同的行开头,最终会相互死锁。
实际上,这不会发生,因为并发删除将以相同的顺序进行锁定,从而排除任何可能的死锁。我们在同一个事务中需要额外的并发事务或更多命令,试图无序地锁定资源。
但所有这些都是 完全无关,因为要更新的列也在WHERE
子句中。 (即使涉及列上的索引。)由于Postgres的MVCC模型,它无论如何都会编写新的行版本,无论哪些列实际更新。
如果您应该遇到涉及无序行锁的死锁,您可以使用SELECT .. FOR UPDATE
使用确定性 ORDER BY
解决此问题在子查询中: