postgresql – 涉及外键约束的死锁

postgresql – 涉及外键约束的死锁,第1张

概述我想更好地理解postgres中的锁定机制. 假设树可以有苹果(通过苹果桌上的外键).似乎在选择树时进行更新锁定是在苹果上获得的.但是,即使其他人已经锁定了这个苹果, *** 作也不会被阻止. 为什么会这样? 附:请不要建议删除“选择更新”. 脚本 Transaction 1 Transaction 2BEGIN .update apple; .. 我想更好地理解postgres中的锁定机制.

假设树可以有苹果(通过苹果桌上的外键).似乎在选择树时进行更新锁定是在苹果上获得的.但是,即使其他人已经锁定了这个苹果, *** 作也不会被阻止.

为什么会这样?

附:请不要建议删除“选择更新”.

脚本

Transaction 1      Transaction 2BEGIN              .update apple;      ..                  BEGIN.                  select tree for update;.                  update apple;.                  --halts because of the other transaction locking an appleupdate apple;      .-- deadlock        .                   COMMIT                   --transaction succeeds

如果你想在你的postgres中尝试 – 这是一个你可以复制/粘贴的代码.

我有一个以下的数据库架构

CREATE table trees (    ID       integer primary key);create table apples (    ID       integer primary key,tree_ID  integer references trees(ID));

而且非常简单的数据

insert into trees values(1);insert into apples values(1,1);

有两个简单的交易.一个是更新苹果,第二个是锁定树并更新苹果.

BEGIN;    UPDATE apples SET ID = ID WHERE ID = 1;    -- run second transaction in paralell    UPDATE apples SET ID = ID WHERE ID = 1;COMMIT;BEGIN;    SELECT ID FROM trees WHERE ID = 1 FOR UPDATE;    UPDATE apples SET ID = ID WHERE ID = 1;COMMIT;

当我运行它们时 – 第一次事务的第二次更新发生死锁.

ERROR:  deadlock detectedDETAIL:  Process 81122 waits for ShareLock on transaction 227154; blocked by process 81100.Process 81100 waits for ShareLock on transaction 227153; blocked by process 81122.CONTEXT:  sql statement "SELECT 1 FROM ONLY "public"."trees" x WHERE "ID" OPERATOR(pg_catalog.=)  FOR SHARE OF x"
解决方法 只是一个疯狂的猜测:你遇到了与实现细节相关的问题……

具体来说,update语句的select树获取树上的独占锁. update apples语句获得对相关苹果的独占锁定.

当您在Apple上运行更新时,Postgres的每行相关的外键触发器会触发,以确保tree_ID存在.我不记得他们的精确名字在我的头顶,但它们在目录中,文档中有一些零碎的部分明确地或隐含地引用它们,例如:

create constraint trigger ... on ... from ...

http://www.postgresql.org/docs/current/static/sql-createtrigger.html

无论如何,这些触发器将运行相当于以下内容:

select exists (select 1 from trees where ID = 1);

这就解决了你的问题:由于select for update的独占访问使得它等待事务2释放树上的锁以便最终确定其对apple的更新语句,但事务2正在等待事务1完成以便获取对苹果的锁定,以便开始对苹果进行更新.

结果,Postgres陷入僵局.

总结

以上是内存溢出为你收集整理的postgresql – 涉及外键约束的死锁全部内容,希望文章能够帮你解决postgresql – 涉及外键约束的死锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1160649.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存