当我从 sys.dm_tran_locks 调用 OBJECT_NAME(object_id, database_id) 时,为什么会被阻止?

Ken*_*her 4 sql-server metadata sql-server-2008-r2 dmv blocking

我正在处理一个查询,以判断给定会话中哪些对象具有锁定,但我遇到了一些阻塞问题。

这是我的基本查询:

SELECT request_session_id AS session_id, 
    request_owner_id AS transaction_id,
    OBJECT_SCHEMA_NAME(resource_associated_entity_id, resource_database_id),
    OBJECT_NAME(resource_associated_entity_id, resource_database_id),
    COUNT(1) AS lock_count
FROM sys.dm_tran_locks WITH (NOLOCK)
WHERE resource_type = 'OBJECT'
GROUP BY request_session_id, request_owner_id, 
    resource_database_id, resource_associated_entity_id
Run Code Online (Sandbox Code Playgroud)

当我运行此查询时,我偶尔会被实际持有锁的会话之一阻止。如果我删除OBJECT_NAMEOBJECT_SCHEMA_NAME然后我没有任何问题。我试过将信息转储到一个表中,然后在有类似问题的表中使用这些值的函数。

这让我相信问题出在OBJECT_NAMEOBJECT_SCHEMA_NAME函数中,但我不确定为什么或如何解决它。我也不确定为什么我有时会被阻止有时不会。有没有人有什么建议?

Aar*_*and 8

因为元数据函数不遵守事务隔离语义。如果您想避免被阻止,请加入sys.schemassys.objects代替使用元数据功能。这也将允许您在单个语句中设置隔离级别,而不是NOLOCK在整个查询中添加提示...

这是 Adam Machanic 在几个版本前在 Connect 上报道的:

http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=432497

因无法修复而关闭。

  • 实际上,NOLOCK 提示是我修复该问题的尝试之一,但没有成功。当我将代码放入问题时我错过了。不幸的是,只有当我为单个数据库提取数据时,加入 sys.schemas 和 sys.objects 才有效。“OBJECT_*”函数有一个我可以添加的附加“database_id”参数。 (2认同)