SQL Server查询使用键查找时锁申请及释放顺序

数据库 SQL Server
最近看了高兄的一篇文章,SQL Server高频,高并发访问中的键查找死锁解析,很有收获,里面讲到了键查找引起的死锁问题。

 当然看的过程中,其实自己有个疑问:

对于键查找这类查询,会申请哪些锁,锁申请和释放的顺序是怎样的?

准备

备注:测试表仍然使用高兄文中创建的测试表testklup

在开始之前,使用dbcc ind 命令先看下测试表的数据组织情况

然后语句执行计划图如下:

查看申请了哪些锁

为了得到查询会申请哪些锁,通过如下这条查询就可以得到

  1. begin tran  
  2. select cont2 from testklup with(HOLDLOCK) where nlskey=1 

 

在默认的事务隔离级别下,开启事务,然后查询中使用HOLDLOCK提示。HOLDLOCK将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立即释放锁。

然后使用DMV视图sys.dm_tran_locks来查看持有锁的情况,查询结果如下:

从查询结果,可以得出申请了如下的锁:

1)在表object上申请了IS锁

2)在非聚集索引PAGE上申请了IS锁

3)在非聚集索引KEY上申请了S锁

4)在聚集索引的PAGE上申请了IS锁

5)在聚集索引的KEY上申请了S锁

查看锁申请和释放的顺序

我们使用SQL Profiler来跟踪锁申请和释放的事件。模板选择TSQL-LOCKS,只跟踪运行语句的会话spid,同时事件增加Lock:Acquired和Lock:Released。执行查询跟踪结果如下:

 

从上图可以得出如下信息:

1) 非聚集索引申请的S锁需等到键查找在聚集索引上查找完毕后才释放。这其实也是键查找导致死锁发生的条件

2)锁申请和释放的顺序有点类似于进栈和出栈,先申请的***释放

3)疑问:为什么没有键查找在聚集索引Key上申请的S锁记录呢?锁肯定是有,但不清楚为什么Profiler没有记录到,因为我跟踪查询加HOLD时,是会在***申请一个S锁的,结果如下:

小结

通过本文,我们知道了一个简单的键查找查询会申请哪些锁,同时,锁申请和释放的顺序是怎样的。在非聚集索引上申请的锁一直到键查找执行完毕才会释放。

原文链接:http://www.cnblogs.com/JentleWang/p/3911167.html

责任编辑:彭凡 来源: 博客园
相关推荐

2010-10-21 14:54:32

查询SQL Serve

2010-09-25 11:50:47

sql server外

2011-09-08 16:30:59

SQL Server查询

2010-10-21 10:28:13

SQL Server查

2010-09-13 13:58:29

sql server外

2010-11-09 11:40:14

SQL Server查

2010-11-09 13:58:03

SQL Server锁

2023-08-02 10:58:18

SP_WHOSQL Server

2010-06-29 17:17:44

SQL Server锁

2010-09-26 16:44:51

SQL子查询

2010-09-26 16:39:27

SQL子查询

2010-06-29 17:52:02

SQL Server嵌

2010-11-09 13:47:17

SQL Server资

2021-01-19 05:39:17

SQLServer变量

2023-08-15 08:26:34

SQL Server查找死锁

2019-11-06 09:30:35

SQL查询语句数据库

2010-06-29 17:32:13

SQL Server锁

2022-08-02 08:00:49

sleepwait释放锁

2020-07-22 08:06:46

释放锁synchronize线程

2010-09-14 14:07:53

SQL Server
点赞
收藏

51CTO技术栈公众号