2012-11-28 34 views
2

假設我們有一個t1表,其中整數weight列被標記爲唯一,item_id是主鍵。以下查詢可以失敗嗎?這個查詢競賽條件是免費的嗎?

UPDATE t1 
    SET weight = SELECT new_weight FROM (
    SELECT MAX(weight) + 1 AS new_weight FROM t1 
) qs 
WHERE item_id = ? 

其中?是一個參數。有可能是因爲一場比賽兩項物品會試圖設定相同的重量?或者那個數據庫引擎是特定的?

+0

這取決於數據庫引擎以及正在使用的隔離級別(如果適用)。 –

+0

如果您的數據庫管理系統支持序列,自動編號或標識列,則應該使用它們。否則,您爲多個用戶唯一安全的選擇就是序列化對錶的訪問權限,即爲您的交易鎖定表。 –

回答

2

是的,你可以得到兩個相同的重量值由於競爭條件。切換到ISOLATION LEVEL SERIALIZABLE以避免這種情況(您可能會遇到一個死鎖,而您可以重試,但您可以避免任何數據損壞)。或者採用RDBMS特有的適當的悲觀鎖定。

+0

擊敗我11秒:) – ppeterka

0

如果兩個事務並行執行,這是可能的。

這兩個事務都會得到相同的值MAX(weight)+1,然後嘗試使用相同的值進行更新,從而導致違反約束。