The Curious Case of the Dubious Deadlock and the Not So Logical Lock や Undocumented Virtual Column: %%lockres% を見て初めて知りました。
SQL Server ではテーブル内の情報を取得する際にはロックを取得します。
DMV では sys.dm_tran_locks、SQL Server Profiler では、lock::acquire のイベント、拡張イベントでは lock_acquired を使用することで、取得されているロックや要求したロックの情報を取得することができます。
今まで知らなかったのですが、 %%lockeres%% を使用することで、ロックのリソースを確認することができるようです。
この手のアンドキュメントの仮想列 (Virtual Column) としてはページの情報を取得するために使用していた %%physloc%% は知っていたのですがロックのパターンは知りませんでした。
以下のようなクエリを実行すると行ごとにロックのリソースを取得することができます。
SELECT TOP 10 *,%%lockres%% AS LockResource FROM LockTest |
SELECT TOP 10 *,%%lockres%% FROM LockTest |
リソースだけですと情報がわかりませんのでロックの DMV と結合をしてみます。
そうすると以下のように行単位にどのようなロックが取得されたのかを確認することができました。
SELECT TOP 10 |
実際にはインテントロックやデータベースの共有ロックもかかっているはずなのですべてのロックの情報が取得されているというわけではありませんが、動作を確認する上では便利そうですね。
ロックのモードを変更すると、行の情報も変わっていました。
以下のクエリはカバードインデックスのみで検索した場合の結果になるのですが、この場合はうまくリソースの情報を割り当てることができませんでした。
KEY ロック
また、行バージョニングによる読み取り制御 (READ COMMITTED SNAPSHOT) を使用した場合も同様にリソースの情報とロックの情報を割り当てることができませんでした。
# こちらは動作としてロック取得でないのでまぁそうなのかなと。
使いこなすためにはまだまだ勉強しないといけませんがなかなか面白そうな情報ですね。
書籍としては MicrosoftR SQL ServerR 2008 Internals (Pro – Developer) / Professional SQL Server 2008 Internals and Troubleshooting / Professional SQL Server 2012 Internals and Troubleshooting に少し記載がされているのですが今まで気づきませんでした。
# 日本語の書籍ではまだ紹介されていなさそうですね。