没有显式锁定的postgres死锁

时间:2013-04-16 17:06:41

标签: postgresql transactions database-deadlocks

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

2 个答案:

答案 0 :(得分:6)

您不需要任何明确的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等待ShareLock   交易4150;被过程9501阻止   过程9501等待   交易4149上的ShareLock;被程序9571阻止    提示:见   服务器日志查询详细信息。

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

答案 1 :(得分:2)

我首先怀疑哈希索引。

  • 将您拥有的所有hash - 索引切换为B-tree
  • 如果合适,请使用Serializable隔离级别。