看着
update MyTable
set Status = 1
where Status = 0
当然 -where
是在实际更新之前计算的。
但是这个过滤(where Status = 0
)是否也在锁内?
我的意思是锁在哪里?
这里 :update ...
或在这里: filter and update...
看着
update MyTable
set Status = 1
where Status = 0
当然 -where
是在实际更新之前计算的。
但是这个过滤(where Status = 0
)是否也在锁内?
我的意思是锁在哪里?
这里 :update ...
或在这里: filter and update...
更新数据的锁定有两个阶段。第一个是更新锁(U),第二个是排他锁(X),如果有需要修改的数据。从某种意义上说,这是一个两阶段操作,需要搜索数据以确定需要修改什么/是否需要修改数据。为此将存在更新锁(或在操作期间尝试获得)。然后当需要修改数据时,更新锁会转换为排他锁。
这种锁定机制背后的原因是为了防止更新数据场景中的死锁。请参阅Kalen Delaney 的帖子,了解有关此问题的更多细节。
以下面为例:
对连接 1 执行此操作...
然后在另一个会话中,尝试以下更新:
我们这里有一个正在等待的更新锁,因为更新锁试图获取的资源上已经有一个排他锁(更新锁与排他锁不兼容)。上述场景用于“停止”更新锁转换为排他锁。
您可以通过查看
sys.dm_tran_locks
DMV 看到这一点:对于上述查询的输出,您应该有类似的结果: