2011-10-18 85 views
1

我有一個SQL語句做更新,然後如果@@ROWCOUNT是0,它會插入。這基本上是SQL 2008.中的一個MERGE。我們遇到兩個線程同時失敗的情況。它會嘗試在表中插入相同的密鑰兩次。我們正在使用默認事務隔離級別Read Committed。將水平改爲可重複讀取可以解決這個問題,還是我必須一路走到Serializable才能完成這項工作?這裏是一些代碼:修復交易隔離級別重複讀取的問題?

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

BEGIN TRAN;            
UPDATE TableA 
SET Duration = @duration    
WHERE keyA = @ID 
AND keyB = @IDB; 

IF @@rowcount = 0 
BEGIN 

INSERT INTO TableA (keyA,keyB,Duration) 
VALUES (@ID,@IDB,@duration); 

END 
COMMIT TRAN; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;"; 
+0

您不會因爲讀取已提交事務隔離級別而進行髒讀操作。讀取未提交只能獲得髒讀。 – 2011-10-19 00:43:17

+0

不好意思說 - 做更新和插入原子。我如何結合他們 – Ryan

回答

1

你需要去所有的方式高達SERIALIZABLE

REPEATABLE READ如果該行不存在,那麼兩個UPDATE語句可以同時運行而不會相互阻塞並繼續進行插入。在SERIALIZABLE下,該行將被阻止的範圍。

但是,您還應該考慮將隔離級別保留爲默認read committed並在keyA,keyB上添加一個唯一約束,以便任何嘗試插入副本都會失敗並返回錯誤。