2010-06-27 54 views
2

數據庫中有表X和表的,BN,CN,DN,從X.訂單查詢(PostgreSQL的)鎖

過程1個查詢週期性地從X.

數據過程2繼承的更新子表中的數據。例如,要更新表An和Bn,它會創建新的表Am和Bm,將數據加載到它們中,鎖定訪問專用An,Bn,並將An和Bn放入並更改Am和Bm以繼承X.

問題是當進程1執行查詢時(例如select * from X)它以共享模式鎖定表An,Bn,Cn,Dn,並且鎖定順序未知。如果進程1鎖定了Bn,那麼進程2鎖定我們有死鎖。

有沒有關於在postgresql查詢鎖定表的順序(沒有顯式鎖定)?或者可能有其他解決方案是可能的?

+0

SELECT不鎖定表格,除非您明確要求鎖定。你有沒有檢查pg_locks來看看發生了什麼? http://www.postgresql.org/docs/8.4/interactive/view-pg-locks.html – 2010-06-28 06:28:01

+0

SELECT鎖表(http://www.postgresql.org/docs/8.1/static/explicit-locking.html) ,並在我的情況下,它與專門請求刪除的訪問衝突。 訪問共享 僅與ACCESS EXCLUSIVE鎖定模式衝突。 SELECT和ANALYZE命令在引用的表上獲取此模式的鎖定。一般來說,任何只讀取一個表並且不修改它的查詢都會獲得這種鎖定模式。 – valodzka 2010-06-28 09:21:15

+0

它因爲ACCESS EXCLUSIVE而發生衝突,那就是你的問題。 SELECT本身不是問題。 – 2010-06-28 11:08:14

回答

1

我知道你說的沒有明確的鎖定,但老實說你最好在這裏下注顯式鎖定。由於這兩個批次中的第一條語句都有一個lock命令來鎖定您將使用的表。關於這一點最重要的部分是lock命令必須以相同的順序鎖定表,否則無論如何你會再次遇到死鎖。

之後,確保兩個批次的運行速度儘可能快,因爲您正在使用表級別鎖定...您不想再持有這些鎖定時間。

+0

我簡化了一下:進程1不是批處理作業,它是很多執行很多不同查詢的處理程序。對每個查詢使用顯式鎖定會非常煩人。 如果postgresql的順序是可預測的,那麼更改進程2的鎖定順序將會非常簡單。 – valodzka 2010-06-27 21:07:41

+0

這就是爲什麼你不應該過分簡化你的問題。儘管如此,選項仍然保持不變:要麼執行顯式鎖定,要麼處理失敗時的死鎖(因爲postgres檢測到死鎖並殺死其中一個proclasses,因此另一個可以完成這是一個選項)。 – Donnie 2010-06-27 21:11:02

0

是否存在有關的查詢 鎖定表的順序 PostgreSQL的任何信息(沒有明確鎖定)? 或者可能是其他解決方案是 可能嗎?

正常情況下,postgresql的mvcc實現可以防止許多類型的死鎖。有關更多詳情,請參閱http://www.postgresql.org/files/developer/transactions.pdf

雖然,一個常見的解決方案是隻處理死鎖,也就是說,如果您的查詢由於死鎖而失敗,請重試。