Sql server 更新查询锁定阶段?

Roy*_*mir 4 sql-server-2008 sql-server locking

看着

update MyTable
set Status = 1
where Status = 0
Run Code Online (Sandbox Code Playgroud)

当然 -where在实际更新之前计算。

但是这个过滤(where Status = 0)也在锁里面吗?

我的意思是锁在哪里?

这里 : update ...

或在这里: filter and update...

Tho*_*ger 6

更新数据的锁定有两个阶段。第一个是更新锁 (U),第二个是排他锁 (X),前提是有数据需要修改。从某种意义上说,这是一个两阶段操作,需要搜索数据以确定需要修改什么/是否需要修改数据。更新锁将存在(或尝试在操作期间获得)。然后当需要修改数据时,更新锁会转换成排它锁。

这种锁定机制背后的原因是为了防止更新数据场景中的死锁。请参阅Kalen Delaney 的帖子,了解有关此问题的更多细节。

以下面为例:

为连接 1 执行此操作...

-- connection 1, leaves an open tran to prevent connection 2 from progressing

use AdventureWorks2012;
go


begin tran

    update HumanResources.Department
    set name = 'This is a new name'
    where DepartmentID = 11;

--commit tran
Run Code Online (Sandbox Code Playgroud)

然后在另一个会话中,尝试以下更新:

use AdventureWorks2012;
go

update HumanResources.Department
set name = 'This is a conflicting tran'
where DepartmentID = 11;
Run Code Online (Sandbox Code Playgroud)

我们这里有一个正在等待的更新锁,因为更新锁试图获取的资源上已经有一个排他锁(更新锁与排他锁不兼容)。上述场景用于“停止”更新锁向排他锁的转换。

你可以通过查看sys.dm_tran_locksDMV来看到这一点:

use AdventureWorks2012;
go

select
    resource_type,
    resource_description,
    resource_associated_entity_id,
    request_mode,
    request_status
from sys.dm_tran_locks
where resource_database_id = db_id();
Run Code Online (Sandbox Code Playgroud)

对于上述查询的输出,您应该有类似的结果:

在此处输入图片说明