2014-09-29 48 views
0

似乎經常詢問這個話題,而且我認爲我找到了一個answer作爲我原來的問題,但現在我很好奇這個(和我發現了一些其他的答案),我的SQL:用於WHERE子句和子SELECT的UPDATE的SQL Server鎖定

update Foos set Owner = 'me' OUTPUT INSERTED.id where Owner is null and id in 
    (select top 1 id from Foos where Owner is null) 

我現在明白了,我的原假設是正確的關於子選擇和併發性,在併發線程可以select相同id作爲另一個線程即將update那個ID。但是,update件中的where子句是否有助於防止這種競爭條件(在read committed級別)?

我的理論是,當兩個線程可以從子select得到相同的ID,只有一個將能夠update,因爲update是原子,包括條件。另一個線程會失敗,或更新零記錄。真的嗎?

+0

哎呀看起來也許這應該已經張貼在DBA?從來不知道存在...... – Josh 2014-09-29 16:23:42

+0

除了併發性問題之外,您正在做一個沒有訂單的前1名。除非您指定訂單,否則您可能無法獲得相同的1。 – 2014-09-29 16:30:12

回答

0

試試這個

;WITH CTE AS 
(
    SELECT ID, [Owner] 
    , ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) rn 
    FROM Foos 
    WHERE [Owner] IS NULL 
) 
update CTE 
    SET [Owner] = 'me' 
OUTPUT INSERTED.id 
WHERE rn = 1