web-dev-qa-db-ja.com

SQL ServerのCONTEXT_INFOのスコープは何ですか?

CONTEXT_INFOを使用して、監査/履歴テーブルの目的でユーザー名を削除トリガーに渡します。 CONTEXT_INFOの範囲と、潜在的な競合状態を作成しているかどうかを理解しようとしています。

私の各データベーステーブルには、削除を処理するためのストアドプロシージャがあります。ストアドプロシージャの削除は、userIdをパラメーターとして受け取り、CONTEXT_INFOをuserIdに設定します。次に、削除トリガーがCONTEXT_INFOを取得し、それを使用して、行を削除したユーザーを示す監査テーブルを更新します。

問題は、異なるユーザーからの2つの削除sprocが同時に実行されている場合、一方のsprocに設定されたCONTEXT_INFOは、もう一方のsprocによって起動されたトリガーによって消費される可能性があるかどうかです。

この記事を見たことがあります http://msdn.Microsoft.com/en-us/library/ms189252.aspx しかし、SQLServerのセッションとバッチの範囲が明確ではありません。役立つ記事の鍵!

コードを投稿したいのですが、現時点では時間が足りません。これが十分に明確でない場合は、後で編集します。

助けてくれてありがとう。

24
JasonS

コンテキスト情報にはスコープがなく(言語変数スコープの意味で)、セッションの存続期間にバインドされます。一度設定されると、コンテキスト情報は、接続が閉じられるまで(セッションが終了するまで)、または新しい値が設定されるまで、設定された値のままになります。セッションでの実行は常にシーケンシャルであるため、並行性の問題はありません。

プロシージャでコンテキスト情報を設定した場合、そのセッションでその後実行されるトリガーには、新しく設定されたコンテキスト情報の値が表示されます。提案するようにコンテキスト情報にユーザーID値を設定し、それをトリガーで使用することは、コンテキスト情報の使用の典型的な例であり、基本的に並行性について話すことはないため、並行性に関して完全に安全です。ストアドプロシージャでコンテキスト情報を設定し、そのプロシージャで発生した削除が原因で実行されるトリガーでそれを信頼する場合、バッチはまだ終了していないため、リンクした記事によると、 _sys.dm_exec_requests_ DMVまたはCONTEXT_INFO()関数からのconetxt情報。まだ_sys.dm_exec_sessions_にプッシュされません。これは、ストアドプロシージャを終了し、サーバーに送信されたT-SQLバッチ内の他の呼び出し(「要求」)を終了した後にのみ発生します。

30
Remus Rusanu

私は1つのクライアントサイトでこの正確な監査方法を使用しましたが、6か月近くも問題なく頻繁に使用しています。

コンテキスト情報のスコープは、現在のバッチの現在の接続と、現在のバッチの完了後に開始されるすべてのバッチです。環境内の2人のユーザーは、同じ接続を使用していないか、接続を共有している場合でも、重複していても独自の値を持ちます。次々と来ると、2番目のものが最初のものを上書きしますが、とにかくそれまでにそれで行われていたでしょう。少なくとも、これはそれがどのように機能するかについての私の理解です。詳細については、MARS(複数のアクティブな結果セット)を検索できます。

6
Tom H