SQL Server 2008 R2のテーブルでいくつかの削除、更新、および挿入を実行するトランザクション(T1などと呼ばれる)が長時間実行されています。同時に、別のプロセスが定期的にこのテーブルの選択ステートメントを実行します。
デフォルトの分離設定(READ COMMITTEDだと思いますか?)では、T1は、トランザクションがコミットまたはロールバックされるまで、selectステートメントの実行をブロックします。
私が見たいのは、トランザクションが進行中でも、selectステートメントが一貫したデータで機能することです。スナップショット分離が役立つと思いますが、正しい方向に進んでいるかどうかはわかりません。これは、このアプリケーションに最適な分離レベルでしょうか?
次に、selectステートメントを呼び出すプロセスを制御することはできませんが、T1を呼び出す.NETアプリケーションを制御します。 selectステートメントとT1の両方で分離レベルの変更が必要ですか、それともT1だけを別の分離レベルとしてマークするだけで十分でしょうか?
理想的な世界では、SNAPSHOTとREAD COMMITTED SNAPSHOT(RCSI)の2つの選択肢があります。ワークロードにどちらが適切かを決定する前に、 トランザクション分離レベルの基本 を理解してください。具体的には さまざまな結果に注意してください RCSIに移行した結果として表示される場合があります。
これは、selectステートメントを生成しているアプリケーションを制御できないため、理想的な世界ではないようです。その場合、あなたの唯一のオプションは、selectがREAD COMMITTEDではなくRCSIを自動的に使用するように、問題のデータベースに対してRCSIを有効にすることです。
正しい、SNAPSHOT分離を使用して、トランザクションが開始する前から一貫したコミット済みデータを取得します。
READ UNCOMMITTED分離(別名NOLOCKヒント)は、dirtz、一貫性のないデータを読み取ります
SNAPSHOT分離を有効にすると、それ以降のすべてのSELECTに有効になります。あなたが実行します - ALTER DATABASE
この場合、READ_COMMITTED_SNAPSHOT
編集:リンク+ ALTER DATABASEの引用(私の太字)
データベースレベルでRead-Committed Snapshotオプションを有効にします。有効にすると、DMLステートメントは、トランザクションがスナップショットアイソレーションを使用していない場合でも、行バージョンの生成を開始します。このオプションを有効にすると、コミットされた読み取り分離レベルを指定するトランザクションは、ロックではなく行のバージョン管理を使用します。トランザクションが読み取りコミットされた分離レベルで実行される場合、すべてのステートメントは、ステートメントの開始時に存在するデータのスナップショットを参照します。
そして スナップショット分離の使用 (私の太字)
READ_COMMITTED_SNAPSHOTデータベースオプションは、データベースでスナップショット分離が有効になっている場合のデフォルトREAD COMMITTED分離レベルの動作を決定します。 READ_COMMITTED_SNAPSHOT ONを明示的に指定しない場合、READ COMMITTEDはすべての暗黙的なトランザクションに適用されます。これは、READ_COMMITTED_SNAPSHOT OFF(デフォルト)の設定と同じ動作を生成します。 READ_COMMITTED_SNAPSHOT OFFが有効な場合、データベースエンジンは共有ロックを使用してデフォルトの分離レベルを適用します。 READ_COMMITTED_SNAPSHOTデータベースオプションをONに設定すると、データベースエンジンは、ロックを使用してデータを保護する代わりに、行のバージョン管理とスナップショット分離をデフォルトとして使用します。
あ、はい。
RCSIを有効にすると、読み取りで一貫性のあるデータを取得でき、ライターによってブロックされずに、Read Committedを引き続き使用できます。
次の質問とその回答をお読みになることをお勧めします: データベースロックの問題? 。
Dbレベルで使用する適切な分離レベルを見つけることは、この問題を解決するために今すぐ実行できる最も速いことです。データベースにアクセスするすべてのアプリケーションを変更してコードを変更することは現在困難であるためです。 「selectステートメントを呼び出しているプロセスを制御することはできない」とおっしゃっていたので、最も速い答えは、dbをRead Committed Snapshot分離レベルに切り替えることです。そうすれば、読み取りクエリに触れることはありません。それ以外の場合は、大きなトランザクション中にデータを読み取るセッションにスナップショット分離レベルを使用する必要があります。
正しいものを選択することについての詳細: 行のバージョン管理ベースの分離レベルの選択 。