检测 SQL 服务器更新锁定的原因



问题

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

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

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

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

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

我尝试过:

  1. 正在探索活动监视器 - 它显示查询被锁定挂起。按头部拦截器过滤不会提供太多,它经常变化。

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

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

数据库详细信息

  • 版本: SQL Server 2016
  • 应用每秒对数据库的并发查询数的大致数:400
  • 数据库大小:1.5 TB
  • 事务
  • 隔离级别:只读事务ReadUncommitedSerializable修改的事务

我对这类问题绝对是新手,所以我肯定错过了很多。
任何帮助或指导都会很棒!

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

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>锁的事务以及它们现在正在执行的查询。

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

最新更新