从wait_type入手模拟SQL Server Lock

一、LCK_M_S,等待获取共享锁

开始一SQL TRAN,其中执行对某数据的UPDATE。但并不COMMIT,也不ROLLBACK。

begin tran
update [dbo].[HR_Employee] set [Description]='ZZ'

这样,便使用排它锁锁定了该[Employee]表。

 

在另一会话中,执行对该表的SELECT操作。至此,死锁产生。

select * from [dbo].[HR_Employee]

 

使用下列script查询当前锁情况。

复制代码
 1 SELECT wt.blocking_session_id                    AS BlockingSessesionId
 2         ,sp.program_name                           AS ProgramName
 3         ,COALESCE(sp.LOGINAME, sp.nt_username)     AS HostName    
 4         ,ec1.client_net_address                    AS ClientIpAddress
 5         ,db.name                                   AS DatabaseName        
 6         ,wt.wait_type                              AS WaitType                    
 7         ,ec1.connect_time                          AS BlockingStartTime
 8         ,wt.WAIT_DURATION_MS/1000                  AS WaitDuration
 9         ,ec1.session_id                            AS BlockedSessionId
10         ,h1.TEXT                                   AS BlockedSQLText
11         ,h2.TEXT                                   AS BlockingSQLText
12   FROM sys.dm_tran_locks AS tl
13   INNER JOIN sys.databases db
14     ON db.database_id = tl.resource_database_id
15   INNER JOIN sys.dm_os_waiting_tasks AS wt
16     ON tl.lock_owner_address = wt.resource_address
17   INNER JOIN sys.dm_exec_connections ec1
18     ON ec1.session_id = tl.request_session_id
19   INNER JOIN sys.dm_exec_connections ec2
20     ON ec2.session_id = wt.blocking_session_id
21   LEFT OUTER JOIN master.dbo.sysprocesses sp
22     ON SP.spid = wt.blocking_session_id
23   CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
24   CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
复制代码

发现该LOCK的wait_type为LCK_M_S,意味着后一会话在等待着获取对该表的共享锁已完成查询工作。

 

二、LCK_M_U,等待获取更新锁。

发起一SQL会话,在其中使用更新锁(UPDLOCK)SELECT数据,而后WAIT一定的时间。

1 begin tran
2 select * from [dbo].[HR_Employee] WITH (UPDLOCK) where [Id]=7
3 waitfor delay '00:01:00' 
4 update [dbo].[HR_Employee] set [Description]='ZZ' where [Id]=7
5 commit tran

在wait的时间内,[Id]=7的行被更新锁锁住。

 

发起另一会话,使用更新锁(UPDLOCK)完成SELECT操作。

1 select * from [dbo].[HR_Employee] WITH (UPDLOCK)

 

发现后一会话被block。wait_type为LCK_M_U,表示其在等待该表的更新锁。

 

三、LCK_M_X,等待获取排它锁

将上一小节中第二个会话的操作改为UPDATE。

update [dbo].[HR_Employee] set [Description]='ZZy' where [Id]=7

后一会话同样被block,但这次的wait_type为LCK_M_X,表明其在等待用于UPDATE DATA的排它锁。

posted on   iSun  阅读(2126)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
阅读排行:
· 对象命名为何需要避免'-er'和'-or'后缀
· JDK 24 发布,新特性解读!
· Java24你发任你发,我用Java8
· .NET Core奇技淫巧之WinForm使用Python.NET并打包
· C# 中比较实用的关键字,基础高频面试题!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示