• SQLServer 查询使用键查找时锁申请及释放顺序


    最近看了高兄的一篇文章,Sql Server 高频,高并发访问中的键查找死锁解析,很有收获,里面讲到了键查找引起的死锁问题。
    当然看的过程中,其实自己有个疑问:
    对于键查找这类查询,会申请哪些锁,锁申请和释放的顺序是怎样的?
     
    准备
    备注:测试表仍然使用高兄文中创建的测试表testklup
    在开始之前,使用dbcc ind 命令先看下测试表的数据组织情况
    然后语句执行计划图如下:
     
    查看申请了哪些锁
     
    为了得到查询会申请哪些锁,通过如下这条查询就可以得到
    begin tran 
    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来跟踪锁申请和释放的事件。
    备注:也可以在执行语句前,开启1200跟踪标记,使用语句dbcc traceon(1200,-1) (感谢CareySon)
    模板选择TSQL-LOCKS,只跟踪运行语句的会话spid,同时事件增加Lock:Acquired和Lock:Released。执行查询跟踪结果如下:
     
    从上图可以得出如下信息:
    1) 非聚集索引申请的S锁需等到键查找在聚集索引上查找完毕后才释放。这其实也是键查找导致死锁发生的条件
    2)锁申请和释放的顺序有点类似于进栈和出栈,先申请的最后释放
    3)疑问:为什么没有键查找在聚集索引Key上申请的S锁记录呢?锁肯定是有,但不清楚为什么Profiler没有记录到,因为我跟踪查询加HOLD时,是会在最后申请一个S锁的,结果如下:
     
     
    小结
    通过本文,我们知道了一个简单的键查找查询会申请哪些锁,同时,锁申请和释放的顺序是怎样的。在非聚集索引上申请的锁一直到键查找执行完毕才会释放 
     
    如有不对的地方,欢迎拍砖,谢谢!O(∩_∩)O 
     
  • 相关阅读:
    20155307《网络对抗》网络欺诈技术防范
    20155307《网络对抗》信息搜集与漏洞扫描
    20155307《网络对抗》MSF基础应用
    20155307《网络对抗》恶意代码分析
    20155307《网络对抗》免杀原理与实践
    预习非数值数据的编码方式
    预习原码补码
    C语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
  • 原文地址:https://www.cnblogs.com/JentleWang/p/3911167.html
Copyright © 2020-2023  润新知