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