SSMS内置All Blocking Transactions报告为何不显示阻塞SQL语句?
主要有这几个核心原因:
内置报告的数据源范围有限
SSMS的「All Blocking Transactions」报告通常依赖sys.dm_tran_locks、sys.dm_exec_requests这类系统视图获取数据。当连接1执行完INSERT但未提交事务时,该连接此时没有正在运行的请求,sys.dm_exec_requests里对应的sql_handle会是空值,报告无法通过这个句柄关联到之前执行的INSERT语句,所以「Blocking SQL Statement」显示为空。而自定义查询可能会额外关联sys.dm_exec_sql_text、sys.dm_exec_query_stats或者sys.dm_tran_active_transactions等视图,从语句缓存或事务上下文里提取历史执行的SQL。内置报告只关注「正在执行」的阻塞操作
这个报告的设计逻辑可能只追踪当前正在运行的、产生阻塞的语句。但你的场景里,阻塞源是已经执行完毕但未提交的事务持有的锁,而非正在运行的语句。报告没考虑这种“已执行但锁未释放”的情况,自然拿不到阻塞语句。自定义查询则会把事务持有锁的情况纳入判断,通过事务ID关联到该事务执行过的SQL语句。语句缓存的时效性差异
SQL Server的语句缓存(sys.dm_exec_query_stats)会定期清理或覆盖旧的语句信息。内置报告可能没有优先从缓存中查询历史语句,而自定义查询可能主动去缓存中查找匹配的sql_handle或plan_handle,哪怕当前连接没有正在运行的请求,也能从缓存里捞出之前执行的INSERT语句。
内容的提问来源于stack exchange,提问作者user3057544

