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...
更新数据的锁定有两个阶段。第一个是更新锁 (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_locks
DMV来看到这一点:
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)
对于上述查询的输出,您应该有类似的结果:
归档时间: |
|
查看次数: |
2269 次 |
最近记录: |