web-dev-qa-db-ja.com

sys.dm_tran_locksからOBJECT_NAME(object_id、database_id)を呼び出すと、なぜブロックされるのですか?

特定のセッションからどのオブジェクトがロックされているかを確認するクエリに取り組んでおり、いくつかのブロッキングの問題が発生しています。

これが私の基本的な質問です:

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

このクエリを実行すると、実際にロックを保持しているセッションの1つによってブロックされることがあります。 OBJECT_NAMEOBJECT_SCHEMA_NAMEを削除しても、問題はありません。情報をテーブルにダンプしてから、同様の問題があるテーブルの値の関数を使用してみました。

これにより、問題はOBJECT_NAME関数とOBJECT_SCHEMA_NAME関数にあると思いますが、その理由や回避方法がわかりません。また、なぜブロックされることもあれば、ブロックされないこともあるのかわかりません。誰か提案がありますか?

4
Kenneth Fisher

メタデータ関数はトランザクション分離セマンティクスに従わないためです。ブロックされないようにしたい場合は、メタデータ関数を使用する代わりに、sys.schemasおよびsys.objectsに参加してください。これにより、クエリ全体にNOLOCKヒントを追加する代わりに、単一のステートメントで分離レベルを設定することもできます。

これは、いくつかのバージョンの前にConnectでAdamMachanicによって報告されました。

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

修正されないためクローズ。

8
Aaron Bertrand