現象
次のような状況で問題が発生します。
-
Microsoft SQL Server 2008 R2 で ALLOW_SNAPSHOT_ISOLATION と READ_COMMITTED_SNAPSHOT 有効に設定されているオプションを含むデータベースを使用しています。
-
データベースのテーブルに対してTABLOCKとUPDLOCKのヒントを含むSELECTステートメントを実行します。
-
SELECTステートメントは、明示的なBEGIN TRANでラップされますが、 COMMIT tranは実行されません。
-
同じクエリヒントで開始される同じクエリの2つ以上が、明示的なトランザクションに含まれます。
このシナリオでは、最初のクエリがコミットされると、他のクエリのいずれかがデッドロックになります。
原因
この問題は、次のいずれかのシナリオで SQL Server が誤ってデッドロックを報告するために発生します。
-
データベースに対して ALLOW_SNAPSHOT_ISOLATION と READ_COMMITTED_SNAPSHOTを有効にすると、1つのトランザクションが完了したときに、同じトランザクションに対する複数のクエリが誤ってデッドロックとして報告されることがあります。
-
ALLOW_SNAPSHOT_ISOTIONが有効になっていて、ヒントのTABLOCKとUPDLOCKが使用されている場合、2番目と3番目のselectステートメントは、X に変換するためのインテントを使って IX ロックを受け取ります。X への変換を試みたときに、IX ロックがデッドロックを終了します。
-
ALLOW_SNAPSHOT_ISOLATIONを無効にすると、2番目と3番目のクエリで6つのロックが取得されます。 この状況では、6つのロックが X に変換された場合、デッドロックではなく、ブロックシナリオにすぎません。
解決方法
この問題は、SQL Server の次の累積的な更新プログラムで最初に修正されました。 修正プログラムを適用した後、SQL Server は、データベースとクエリで読み取りのコミット ヒントまたは NOLOCK hint が発生したかどうかを記録して、問題を解決します。 この情報は、デッドロックを誤って報告するのではなく、適切な種類のロックを選択して適切な状態を処理するために使われます。
SQL Server 2008 R2 SP2 の累積更新プログラム11 /en-us/help/2926028
SQL Server 用の新しい累積更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとすべてのセキュリティ修正が含まれています。 SQL Server の最新の累積的な更新プログラムを確認します。
状態
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。