本番SQLServer2000データベースで、非常に厄介なデッドロック状態が発生しています。
主な設定は次のとおりです。
- SQL Server2000EnterpriseEdition。
- サーバーは、ATLOLEデータベースを使用してC++でコーディングされています。
- すべてのデータベースオブジェクトは、ストアドプロシージャを介してアクセスされています。
- すべてのUPDATE/INSERTストアドプロシージャは、内部操作をBEGIN TRANS ...COMMITTRANSブロックでラップします。
このようなインターネット上のいくつかの記事に従って、SQL Profilerを使用していくつかの初期トレースを収集しました(SQL Server 2005ツールを参照していることを無視してください。同じ原則が適用されます)。トレースから、2つのUPDATEクエリ間のデッドロックのように見えます。
問題が発生する可能性を減らすために、次のような対策を講じています。
- SELECT WITH(NOLOCK)。ストアドプロシージャのすべてのSELECTクエリをWITH(NOLOCK)を使用するように変更しました。ダーティリードの影響は理解していますが、多くの自動更新を実行し、通常の状態ではUIに適切な値が設定されるため、クエリ対象のデータはそれほど重要ではありません。
- コミットされていないを読んでください。サーバーコードのトランザクション分離レベルをREADUNCOMMITEDに変更しました。
- トランザクションスコープの縮小。データベースのデッドロックが発生する可能性を最小限に抑えるために、トランザクションの保持時間を短縮しました。
また、ストアドプロシージャの大部分(BEGIN TRANS ... COMMIT TRANSブロック)内にトランザクションがあるという事実にも疑問を投げかけています。この状況では、トランザクション分離レベルはシリアライズ可能だと思いますよね?また、ストアドプロシージャを呼び出すソースコードでトランザクション分離レベルも指定されている場合はどうでしょうか。どちらが適用されますか?
これは処理集約型のアプリケーションであり、読み取り(より大きな割合)と一部の書き込みでデータベースに多くの影響を与えています。
これがSQLServer2005データベースの場合、スタックオーバーフローに関するデッドロックの問題について、Geoff Dalgasの回答を使用できます。これが、発生している問題にも当てはまります。ただし、現時点では、SQLServer2005へのアップグレードは実行可能なオプションではありません。
これらの最初の試みが失敗したので、私の質問は次のとおりです。ここからどのように進みますか?デッドロックの発生を減らす、または回避するためにどのような手順を実行しますか、または問題をより適切に明らかにするためにどのコマンド/ツールを使用する必要がありますか?