2

SQL Server 2008 R2 でデッドロックの問題が発生しています。SQL プロファイラーでデッドロック グラフを見ると、問題はクエリ通知に起因するようです。

  <resource-list>
   <keylock hobtid="72057654759522304" dbid="6" objectname="MyDB.sys.query_notification_814081939" indexname="cidx" id="lock15ab2aa80" mode="RangeX-X" associatedObjectId="72057654759522304">
    <owner-list>
     <owner id="process5c5708" mode="RangeX-X"/>
    </owner-list>
    <waiter-list>
     <waiter id="process4e9ae08" mode="RangeS-U" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057654759522304" dbid="6" objectname="MyDB.sys.query_notification_814081939" indexname="cidx" id="lock15e56a300" mode="RangeS-U" associatedObjectId="72057654759522304">
    <owner-list>
     <owner id="process4e9ae08" mode="RangeS-U"/>
    </owner-list>
    <waiter-list>
     <waiter id="process5c5708" mode="RangeS-U" requestType="wait"/>
    </waiter-list>
   </keylock>
  </resource-list>

これらのクエリ通知は、SQLDependency を使用して実装されます。SQLDependency によって監視されているテーブルを更新するときに、デッドロックが発生しているようです。

デッドロック グラフの構文がよくわかりません。KeyLock モードは、シリアライズ可能なトランザクション分離レベルを使用している場合のみ RangeS-U です。、 右 ?

この質問も読みました... READ_COMMITED_SNAPSHOT を有効にする必要がありますか?

どうも...

4

2 に答える 2

2

断定はできませんが、いくつか考えてみます...

通知の原因となったステートメントは、通知が配信される前に完了しない場合があります。したがって、通知が Service Broker から受信され、通知に対して何らかのアクションが実行される時点で、まだアクティブなロックが存在する可能性があります。

最初の通知を生成したトランザクションが完了する前に、通知の受信者がキューをクリーンアップしようとしているか、キューから 2 番目の通知を取得しようとしている可能性があります。

通知を生成した DML はマルチステップ トランザクションで実行されていますか? マルチステップ トランザクションで実行されている通知を受け取るコードです。(つまり、begin tran または同等のものを使用しましたか?)。

デッドロック グラフに示されているプロセスを追跡し、RangeX-X ロックを保持しているコードと RangeS-U を保持しているコードを理解すると役立つ場合があります。

通知を生成するコードとそれを受け取るコードの最小限の例をいくつか投稿することをお勧めします。

また、通知と複数のサブスクリプションに関する既知のやや類似したデッドロックの問題に関する Microsoft KB もあります。

MS KB975090 関連する可能性がありますが、まったく同じではありません。

于 2012-06-08T17:39:46.083 に答える
0

その背後にある主な原因は、トランザクションが長すぎて、オブジェクトが多すぎるという事実です。

質問で述べたように、SqlDependency が発生するテーブルには、データベース内の各オブジェクトへの参照が含まれています。同じトランザクションで一連のオブジェクトを更新すると、クエリ通知システムによってこの大きなテーブルがロックされます。したがって、すぐにデッドロック状態に陥ります。

2 つの解決策 (MS によるアドバイス):

  • トランザクションの長さと複雑さを軽減します。
  • 大きなトランザクションの外部で通知システムをトリガーするリクエストを実行します。
于 2012-10-25T09:36:46.253 に答える