25

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のセッションとバッチの範囲がわかりません。

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

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

4

2 に答える 2

33

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

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

于 2010-06-12T00:51:43.583 に答える
6

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

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

于 2010-06-11T19:46:22.703 に答える