1

デッドロックの問題があります..

データベースの更新に SQL 依存関係を提供しようとしています。

これを行うには、一連のテーブルにトリガーを作成します。テーブルが変更されると、セカンダリ テーブルの整数をインクリメントします。[dbo].[カウンター]. 次に、このテーブルに SQL 依存関係を配置して、どのテーブルがコードから更新されたかを確認します。

ただし、トリガーを配置しているターゲット テーブルはトランザクションで使用される可能性があります。その場合、トランザクションは非常に簡単にデッドロックします。

つまり、tbl1 にはカウンター テーブルを更新するための挿入/更新/削除のトリガーがあります tbl2 にはカウンター テーブルを更新するための挿入/更新/削除のトリガーがあります

トランザクション A がスレッド 1 で発生 tbl1 が変更され、カウンター テーブルの更新がトリガーされる

トランザクション B がスレッド 2 で発生 tbl2 が変更され、カウンター テーブルの更新がトリガーされ、スレッド 2 がブロックされ、スレッド 1 を待機する

一方、スレッド 1 では、トランザクション A が続行され、別のテーブル (tbl1 または tbl2) が更新されます。

ここでデッドロックが発生し、スレッドの 1 つが被害者として選択されます。

私の質問は、デッドロックの可能性を取り除くトリガーを作成するより良い方法があるかどうかです。この問題を回避するために、ASP.NET の既定の SQLDependency がどのように機能するか知っている人はいますか?

4

2 に答える 2

1

要約すると、

デッドロックは、別のトランザクションが増分テーブルで同時に範囲ロックと行ロックを取得したために発生しました。

ASP.NET SQLDependency は、トリガーに ROWLOCK ヒントを使用して、デッドロック シナリオを取り除きます。ただし、これによりブロック動作が導入されるため、2 つのトランザクションが同じ増分テーブルを変更している場合、トランザクションは本質的にシリアル化されます。

MS サポートからの推奨事項は、ROWLOCK Hint を READPAST に変更することです。これにより、増分テーブル内の異なる行が同時に変更されている場合のブロッキング動作が軽減されます。

通知は RDBMS の絶対的な ACID プロパティを必要としないため、高度な戦略として、context_info のような非ブロック グローバル変数を一連のバイナリ フラグとして使用して、行が変更されたという事実を格納することができます (これにより、同じブロック上のブロックが削除されます)。ただし、変数を処理およびリセットするには、呼び出し元のアプリケーションでロジックを変更する必要があります。

于 2013-02-01T17:22:24.993 に答える
1

未使用のカウンター値を許容できますか? その場合は、カウンターを更新するときにトランザクションをドロップアウトします。

于 2013-01-25T23:46:20.607 に答える