我在Postgresql上遇到了一些錯誤,這似乎與這種競爭條件有關。我該如何處理PostgreSQL中的競態條件?
我有一個用Twisted Python編寫的進程/守護進程。描述它的最簡單方法就像Web爬蟲一樣 - 它會拉動一個頁面,解析鏈接並記錄看到的內容。由於HTTP阻塞,Twisted會將多個「併發」進程延遲到線程。
這裏的比賽條件...
當我遇到一個短網址,這樣的邏輯發生:
result= """SELECT * FROM shortened_link WHERE (url_shortened = %(url)s) LIMIT 1;"""
if result:
pass
else:
result= """INSERT INTO shortened_link (url_shortened ..."
一個令人驚訝的數字或psycopg2.IntegrityError的復活,因爲url_shortened唯一索引變侵犯。
select/insert實際上運行在一起。從我所知道的情況來看,它看起來像是兩個縮短的鏈接彼此相鄰排隊。
Process A: Select, returns Null
Process B: Select, returns Null
Process A: Insert , success
Process B: Insert , integrity error
任何人都可以提出任何提示/技巧來處理這個?我想避免明確的鎖定,因爲我知道這會引發另外一些問題。
這應該處理大部分問題。儘管如此,競爭條件的小小機會依然存在。我爲類似的請求寫了一個答案[here](http://stackoverflow.com/questions/15939902/is-my-function-prone-to-race-conditions/15950324#15950324) –
+1 Erwin的函數。這是唯一一個防爆表或諮詢鎖的防彈解決方案。如果有足夠的併發查詢,則此答案的select語句中競態條件的機會決不會忽略不計。 –