2014-09-29 43 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