2012-07-12 57 views
1

最近我們遇到了死鎖問題。我們的系統的兩部分將在類似的時間更新同一個表,一個更新(命名爲「UP1」)在事務中有多行,另一部分(命名爲「UP2」)使用SQL,如「update ... where id在......中「。數據庫如何鎖定行並釋放它們?

看起來好像是因爲這樣,sql中的ids「update ... where id in(...)」出現故障, 「5,6,2,3,4,1」;而在交易中,更新行爲將按照「1,2,3,4,5,6」的順序執行。當「UP1」更新ID「1,2,3,4」和「UP2」更新ID「5,6」時,「UP1」希望由「UP2」鎖定的ID5以及「UP2」想要被「UP1」鎖定的id 2,所以死鎖就出來了。

我的問題是,數據庫鎖的行是一個接一個,只有在sql或事務完成時才釋放它們?如果沒有,爲什麼不能鎖定事務開始處的所有行或「where ID in(...)」sql,爲什麼他們不能一個一個地釋放更新的行?

期待任何有用的回覆,thx。

+0

將是dba.SE.完美契合 – 2012-07-12 19:31:07

回答

1

你幾乎在正確的軌道上。使用默認的Read Committed Isolation Level PostgreSQL一路獲取鎖,並在事務提交或回滾時釋放它們。

如果您可以確保所有UPDATE操作以相同的順序更新行,您將永遠不會遇到死鎖。您是否嘗試按照升序排列UP1更新行,並以相同的方式排列UP2IN列表?

如果您無法保證同步更新,您可能會對Serializable Isolation Level感興趣。它是最嚴格的隔離級別,並且可能會減慢查詢速度,特別是在併發性較高的情況下。但它應該防止你看到的錯誤。另外,請準備好由於序列化失敗而重試事務。

爲此,start your transaction有:

BEGIN ISOLATION LEVEL SERIALIZABLE;