2012-05-04 40 views
2

我感興趣的,什麼是避免小問題:)PostgreSQL的:2+客戶,唯一約束 - >競爭條件

讓我們2個客戶端的最佳實踐,都試圖與唯一約束的表中插入行。
假設它是「url」列。

在同一時間有可能會出現以下情況:
    1)客戶端A看起來,有沒有網址「一」表
    2)客戶端A得到的答案,沒有該網址
    3)客戶端A將要插入網址 「一」
    4)客戶端B看起來,有沒有網址 「一」 表
    5)客戶端B獲取答案,沒有該網址
    6)客戶端A插入網址 「一」
    7)客戶端B是要插入網址 「一」,但得到重複鍵錯誤

難道我的理解對不對,那最好的辦法爲了避免它 - 只需在應用程序級別重試?

回答

1

如果您在SERIALIZABLE隔離級別運行,客戶端B將被強制等待A的交易完成返回該URL的前值。由於該值尚不存在,因此不能在記錄上放置鎖(沒有記錄),因此將使用索引上的間隙鎖定。但是正如@kgrittn所提到的那樣,這會對性能和併發性產生負面影響。所以最好處理重複的鍵錯誤

+2

對於其他一些數據庫來說,這是一個正確的答案,至少在某些配置中是這樣,但對於PostgreSQL來說這是不正確的,這正是問題所在。在PostgreSQL中,SERIALIZABLE事務隔離級別使用可序列化快照隔離,而不是嚴格2階段鎖定,因此不會發生阻塞;仍然會有錯誤。 http://wiki.postgresql.org/wiki/Serializable http://www.postgresql.org/docs/current/interactive/mvcc-intro.html – kgrittn