如果我们有一个带有子SELECT的UPDATE,子查询是否可以在READ COMMITTED隔离下并发执行?
换句话说,以下是否存在竞争条件:
update list set [state] = 'active'
where
id = (select top 1 id from list where [state] = 'ready' order by id)
换句话说,如果许多连接同时执行此SQL,我们是否可以保证每次调用实际更新一行(只要存在“就绪”状态的行)?
答案 0 :(得分:1)
答案是是,存在竞争条件,并且两个事务可能同时执行子查询,导致同一行随后更新两次。
可以通过将更新重写为
来解决此问题update TEMP
set [state] = 'active'
from
(select top 1 * from list where [state] = 'ready' order by id) TEMP
我坦率地不知道为什么这应该有所不同,但确实如此。 SQL Server现在将在执行子查询时采用更新锁(“意图更新”),从而防止并发事务选择同一行。