0

お願いします。最近トラフィックが大幅に増加した実稼働データベースで大量のロックが発生しています。ほとんどのデータ アクセスに IdeaBlade を使用しています。

Sql Profiler を使用して次のトレースを取得しました。

deadlock victim="process84af28"
  resource-list
    keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock45982ac0" mode="X" associatedObjectId="72057594096451584"
      owner-list
owner id="processb852e8" mode="X" 
   owner-list
   waiter-list
    waiter id="process84af28" mode="S" requestType="wait" 
    waiter id="processb855b8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
  keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock513c3bc0" mode="RangeS-U" associatedObjectId="72057594096451584"
   owner-list
    owner id="processb855b8" mode="RangeS-U" 
   owner-list
   waiter-list
    waiter id="processb852e8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
 resource-list
deadlock

アイデアはありますか?

私は DBA ではありませんが、このトレースは次のことを示しているようです。

  1. 子テーブルの行で排他ロック X を持つプロセスが、同じリソースで Select-Update ロックを取得しようとしています (意味がないようです)。

  2. Select-Update ロックを使用する別のプロセスが、引き続き Select-Update ロックを取得しようとしています。

説明はありますか?

デッドロックを最小限に抑える、またはなくすにはどうすればよいでしょうか?

4

4 に答える 4

1

最初に注意すべき点がいくつかあります。

  1. 悲観的ロックの最も制限的な形式であるserializable transactionsを使用しています。おそらく、これは必要ありません (KEY ロックはこの分離レベルにのみ適用されるため、シリアライズ可能なトランザクションを使用していることがわかっています)。Remus が上で述べたように、おそらくここで他のオプションを検討する必要があります。

  2. 上記の出力は少し切り詰められているようです。プロセス情報を spid とクエリにマッピングする情報を含む process-list というセクションが必要です。

上記の出力からわかることは次のとおりです。

processb852e8 owns an exclusive lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName"
    process84af28 is waiting for a shared KEY lock
    processb855b8 is also waiting for a Shared Range-Update KEY lock

processb855b8 owns Shared Range-Update lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName" (the same index)
    processb852e8 is waiting on a Shared Range-Update KEY lock

排他ロックはある種の書き込み (つまり、更新、削除、挿入) であり、RangeS-U ロックは更新である可能性がありますが、マッピングされた情報を見ずに判断する方法はありません。

Bart Duncan は、トレース出力の解読に関する素晴らしい記事をいくつか持っています。また、一般的な同時実行とスクリプトの概要については、こちら を参照してください

于 2009-11-11T01:11:08.063 に答える
0

私は別の製品 (IdeaBlade ではない) でこのデッドロックの問題を見てきました。私の経験では、これはデータベースの問題ではありません。データベースと通信するソフトウェアに問題がある可能性があります。

私の問題は、データベースと通信するコンポーネントの構成にありました。

初めて、COM+ はデフォルトで SERIALIZABLE になり、デフォルトで READ COMMITTED になるように構成する必要がありました。

2 回目は、COM+ から .NET への相互運用状態により、データベース接続がデフォルトで SERIALIZABLE になりました。

私たちにとって、迅速で汚い解決策は、SQL コマンドの前に「SET TRANSACTION ISOLATION LEVEL READ COMMITTED」を付けて、コアの問題が修正されるまで SERIALIZABLE をオーバーライドすることでした。

于 2009-11-11T17:11:22.450 に答える
0

犯人は次のようです:-

owner id="processb855b8" mode="RangeS-U"

これにより、一連の行がロックされたように見えます。最初のプロセスによって行が解放されるのを待っている processb852e8 によって行が解放されるのを待っている process84af28 によって行が解放されるのを待っています。

SQLServer は途中でプロセスを強制終了してデッドロックを解決し、他の 2 つのプロセスを完了させます。

分離レベルを確認する必要があります。ベスト プラクティスは、複数の行を「選択」するときに、利用可能な最低レベルのロックを使用することです。現在のトランザクションで行を更新する可能性が非常に高い場合にのみ、「選択」された行でより高いレベルを使用してください。

また、外部サービスまたはユーザーのアクションを待っている間は、絶対に行をロックしたままにしないでください。

于 2009-11-11T01:44:12.833 に答える
0

mode="RangeS-U"

レンジロック?高いトランザクション分離レベルの使用を停止します。コミットされた読み取りに固執します。CLR TransactionScope オブジェクトを使用する場合は、Read Commited 分離を使用するようにします (デフォルトでは Seralizable を使用します)。データベースでコミット済み読み取りスナップショット分離を有効にしてみてください。スナップショット分離の使用を参照してください。

于 2009-11-11T01:00:32.033 に答える