3

我使用 PostgreSQL 9.2,并且我不在任何地方使用显式锁定,无论是LOCK语句还是SELECT ... FOR UPDATE. 但是,最近我得到了ERROR: 40P01: deadlock detected. 但是,检测到死锁的查询被包装在事务块中。无论如何,它是怎么来的?

4

2 回答 2

9

你不需要任何明确LOCK的进入死锁。这是一个从头开始的非常简单的演示,只有 INSERT:

create table a(i int primary key);
create table b(i int primary key);

第 1 场会议:

begin;
insert into a values(1);

然后会话#2:

begin;
insert into b values(1);
insert into a values(1);
-- here it goes into waiting for session #1 to finish its transaction

然后会话 #1 执行以下操作:

insert into b values(1);

然后发生死锁:

错误:检测到死锁
细节:进程 9571 等待事务 4150 上的 ShareLock;被进程 9501 阻塞。
进程 9501 等待事务 4149 上的 ShareLock;被进程 9571 阻止。
提示:有关查询详细信息,请参阅服务器日志。

简单的 UPDATE 或 UPDATE 和 INSERT 的组合也会发生同样的情况。这些操作采用隐式锁,如果它们以不同的顺序发生在不同的会话中,它们可能会死锁。

于 2013-04-16T18:05:58.217 回答
2

我会首先怀疑哈希索引。

  • hash切换您必须的任何-indexesB-tree
  • Serializable如果看起来合适,请使用隔离级别。
于 2013-04-16T17:51:08.390 回答