2013-04-16 104 views
3

我使用PostgreSQL 9.2,並且我沒有使用任何地方的明確鎖定,既不LOCK聲明也SELECT ... FOR UPDATE。不過,最近我得到了ERROR: 40P01: deadlock detected。儘管檢測到死鎖的查詢被封裝在事務塊中。無論如何,它是如何來的?postgres死鎖沒有明確鎖定

+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); 

然後死鎖oc curs:

ERROR: deadlock detected
DETAIL: Process 9571 waits for ShareLock on transaction 4150; blocked by process 9501.
Process 9501 waits for ShareLock on transaction 4149; blocked by process 9571.
HINT: See server log for query details.

簡單的UPDATE或UPDATE和INSERT的組合也可能發生同樣的情況。 這些操作採取隱式鎖定,如果它們以不同順序發生在不同會話中,則它們可能會死鎖。

2

我會首先懷疑散列索引。

  • 開關任何hash -Indexes你必須B-tree
  • 使用Serializable隔離級別,如果它似乎是適當的。
+0

我沒有任何散列索引,反正他們怎麼會是這個原因? – zapadlo

+1

作爲其實現的一部分,可以使用[hash-bucket-level鎖用於讀/寫訪問](http://www.postgresql.org/docs/9.2/static/locking-indexes.html)。 –