web-dev-qa-db-ja.com

SQL Serverでアプリロックリクエストをキャンセルするにはどうすればよいですか?

sp_getapplock ストアドプロシージャには、次の戻り値があります。

0:ロックは同期的に正常に付与されました。
1:他の互換性のないロックが解放されるのを待った後、ロックは正常に許可されました。
-1:ロック要求がタイムアウトしました。
-2:ロック要求がキャンセルされました。
-3:ロック要求がデッドロックの犠牲者として選択されました。
-999:パラメータの検証またはその他の呼び出しエラーを示します。

私はデータアクセスレイヤーでsp_getapplockを呼び出すためのラッパーを書いています。説明と役立つ例外をスローできるように、-2を返すことができる状況を知りたいです。 -1と-3の戻り値が何を意味するかは明らかであり、これらの値を返すテスト条件を簡単に作成できます。どうすれば-2の戻り値を取得できますか?

25
Heinzi

sp_getapplockラッパープロシージャのソースを見ると、-999を除くすべての戻り値は、基になるsys.xp_userlock内部ストアドプロシージャからのものです。アテンションイベント(クライアントクエリのタイムアウトまたは明示的なクライアントクエリのキャンセル)によって要求がキャンセルされた場合、内部プロシージャは-2を返すと思います。ただし、RETURNステートメントを含め、バッチがキャンセルされた後は、sp_getapplockコードは実行されません。その結果、-2の戻りコードが内部的に返されることがありますが、クライアントが値を取得する実際的な方法はありません。

この理論が正しいと仮定すると、最初に要求をキャンセルしたのはクライアントであるため、-2をより説明的なメッセージに変換することに意味はありません。

ポールでSQLデータベースエンジンのコードをデバッガーで実行することでこれを確認します:-)

6
Dan Guzman

sp_getapplockは、物理オブジェクトではなくセマフォにロックを作成します(MSDNによる)。同じ文字列と互換性のないロックモードを持つsp_getapplockである場合にのみ、別のプロセスをブロックします。

したがって、ロック要求は、より高い特権を持つユーザーがロックを取り消す、サーバープロセスがロックを取り消す、ストアドプロシージャを実行しているユーザー、または管理者がロックプロセスを強制終了するなどの状況で取り消されます。説明は、「システムまたは別のユーザーによってロックが取り消されました」である可能性があります。ロックをキャンセルした実際のプロセス/ユーザーをどのように判断するかわかりません。

1
Ben Schmeltzer