检测SQL Server更新锁定的原因

时间:2017-04-16 06:22:13

标签: sql-server transactions sql-server-2016 database-locking

问题

业务事务期间的.NET应用程序执行类似

的查询
UPDATE Order 
SET Description = 'some new description` 
WHERE OrderId = @p1 AND RowVersion = @p2

此查询会一直挂起,直到超时(几分钟),然后出现异常:

  

SqlException:执行超时已过期。操作完成之前经过的超时时间或服务器没有响应。

当数据库负载很重(每天几次)时,它被复制 我需要检测查询锁定的原因。

我尝试了什么

  1. 探索活动监视器 - 它显示查询是通过锁挂起的。通过headblocker过滤并没有给出太多,它经常变化。

  2. Analyze SQL script, that gives similar to activity monitor data - 与查看活动监视器的结果几乎相同。追逐blocking_session_id导致一些会话,等待命令或执行一些SQL,我无法推断与Order表的关系。在一秒钟内执行相同的脚本会给出其他会话。我也尝试了一个没有结果的some other queries/stored procedures from this atritcle

  3. 为锁定/问题事务构建标准SQL Server报告会导致Max recursion耗尽或Local OutOfMemory Exception(我有16 Gb RAM)等错误。

  4. 数据库详细信息

    • 版本:SQL Server 2016
    • 应用对数据库的每秒大致并发查询数:400
    • 数据库大小:1.5 Tb
    • 事务隔离级别:ReadUncommited用于只读事务,Serializable用于具有修改的事务

    我对这类问题非常陌生,所以我肯定错过了很多 任何帮助或方向都会很棒!

2 个答案:

答案 0 :(得分:1)

尝试使用sys.dm_exec_requests视图,并按列blocking_session_id, wait_time

进行过滤

答案 1 :(得分:1)

如果有人感兴趣,我发现这个特殊的查询特别有用:

SELECT tl.resource_type
 ,OBJECT_NAME(p.object_id) AS object_name
 ,tl.request_status
 ,tl.request_mode
 ,tl.request_session_id
 ,tl.resource_description
 ,(select text from sys.dm_exec_sql_text(r.sql_handle))
FROM sys.dm_tran_locks tl
    INNER JOIN sys.dm_exec_requests r ON tl.request_session_id=r.session_id
    LEFT JOIN sys.partitions p ON p.hobt_id = tl.resource_associated_entity_id
WHERE tl.resource_database_id = DB_ID()
    AND OBJECT_NAME(p.object_id) = '<YourTableName>'
ORDER BY tl.request_session_id

它显示已在<YourTableName>上获取锁定的事务以及它们现在正在执行的查询。