代码之家  ›  专栏  ›  技术社区  ›  Tomas

查找在SQL Server上的查询中获取的锁?

  •  8
  • Tomas  · 技术社区  · 17 年前

    我有一个来自我的应用程序的SQL语句。我想知道该语句获取了哪些锁;如何使用SQL Server实现这一点? 这个声明涉及到一个死锁,我正试图分析它;我无法重现这个死锁。 我在MS SQL Server 2005上运行。

    6 回复  |  直到 10 年前
        1
  •  3
  •   John Sansom    17 年前

    我建议您在第一个实例中打开死锁检测跟踪标志,而不是无限期地运行探查器跟踪。

    这样,事件详细信息将被记录到SQL Server错误日志中。

    有关各种跟踪标志的详细信息,请参阅以下联机丛书参考。您需要使用1204和/或1222

    http://msdn.microsoft.com/en-us/library/ms188396(SQL.90).aspx

    确保启用带有服务器作用域的跟踪标志,而不仅仅是当前会话。例如,使用:

    DBCC TRACEON(1222,-1)
    
        2
  •  4
  •   Andomar    17 年前

    您可以在事务中运行该语句,但不能提交该事务。由于锁将一直保持到提交事务为止,因此这会给您检查锁的时间。(不是无限期的,但默认为5分钟。)

    像:

    BEGIN TRANSACTION
    select * from table
    

    然后打开Management Studio并检查锁。它们在管理中->活动监视器->按对象锁定或按进程锁定。完成后,跑:

    COMMIT TRANSACTION
    

    把锁打开。

        3
  •  3
  •   Rick    17 年前

    这是一个查询,它将显示所有活动的锁,谁拥有这些锁,以及它们所在的对象。我从一篇TechNet的文章或几年前的某个地方找到了这个。它在SQL 2000和2005上工作(将sys objects更改为sys.objects for 2005。)如果要将其仅限于此databse和“exclusive”锁,请取消对where子句的注释。

    select 'Locks' as Locks,
        spid, nt_username, name, hostname, loginame, waittime, open_tran,
        convert(varchar ,getdate() - last_batch, 114) as TimeSinceLastCommand,
        case req_mode
        when  0 then 'Not granted'
        when  1 then 'Schema stability'
        when  2 then 'Schema modification'
        when  3 then 'Intent shared'
        when  4 then 'Shared intent update'
        when  5 then 'Intent shared shared'
        when  6 then 'Intent exclusive'
        when  7 then 'Shared Intent Exclusive'
        when  8 then 'Shared'
        when  9 then 'Update'
        when 10 then 'Intent insert NULL'
        when 11 then 'Intent shared exclusive'
        when 12 then 'Intent update'
        when 13 then 'Intent shared-update'
        when 14 then 'Exclusive'
        when 15 then 'Bulk operation'
        else str(req_mode) end as LockMode
    from master..syslockinfo
        left join sysobjects so on so.id = rsc_objid
        left join master..sysprocesses sp on sp.spid = req_spid
    --where rsc_dbid = (select db_id()) and ltrim(req_mode) in (6,7,11,14) 
    
        4
  •  2
  •   KM.    17 年前

    在探查器中运行跟踪(选择空白模板),选择死锁图事件,并在出现的新标签(事件提取设置)上,将每个(单独保存检查死锁XML事件)保存在自己的文件中。在XML查看器中打开此文件,很容易知道发生了什么。每个进程都包含在其中,有一堆过程调用等,所有锁也都在其中。

    让这个跟踪运行到死锁再次发生为止,信息只在死锁发生时记录,所以开销不大。如果它再也没有发生过,很好,它会被解决,如果不是,你已经捕获了所有的信息。

        5
  •  0
  •   ahains    17 年前

    您可以在您的dev框上运行一个profiler跟踪来进行查询,并准确地查看获取了哪些锁。这通常是一个巨大的数据量,但其中大部分将是您可以浏览的模式。例如,对于读提交隔离,在进行表或索引扫描时,您将看到一系列正在获取和释放的锁(每行在读取前必须锁定,读取后立即释放)。

    你处于什么样的孤立状态?什么样的查询是死锁的?您使用的是包含多个更新的显式事务,还是单语句死锁?

    死锁最典型的情况是具有序列的事务(更新表X,更新表Y),以及具有序列的第二个事务(更新表Y,更新表X)。常见的解决方案是确保在查询之间使用相同的更新序列。

    让我们知道它们是什么类型的查询,对于不同类型的事务有不同的常见问题。