1

问题

业务事务期间的 .NET 应用程序执行如下查询

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

此查询挂起直到超时(几分钟),然后我得到一个异常:

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

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

我试过的

  1. 探索活动监视器 - 它显示查询被锁定。通过 headblocker 过滤并没有提供太多,它经常变化。

  2. 分析 SQL 脚本,给出类似于活动监视器数据的结果 - 与查看活动监视器的结果几乎相同。追逐blocking_session_id 会导致一些会话,等待命令或执行一些SQL,我无法推断与Order 表的关系。在一秒钟内执行相同的脚本会产生其他会话。我还尝试了这个 atritcle 中的一些其他查询/存储过程,但没有结果。

  3. 为锁定/问题事务构建标准 SQL Server 报告会导致错误,如最大递归耗尽或本地 OutOfMemory 异常(我有 16 Gb RAM)。

数据库详细信息

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

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

4

2 回答 2

1

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

于 2017-04-17T12:40:30.977 回答
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>以及它们现在正在执行的查询。

于 2017-04-24T11:00:44.707 回答