SQL Server-非ブロッキングselectステートメントの分離レベルは何ですか?


9

SQL Server 2008 R2のテーブルで一部の削除、更新、および挿入を実行する長時間実行トランザクション(たとえば、T1と呼ばれます)があります。同時に、別のプロセスが定期的にこのテーブルの選択ステートメントを実行します。

デフォルトの分離設定(READ COMMITTEDだと思いますか?)では、T1は、トランザクションがコミットまたはロールバックされるまで、selectステートメントの実行をブロックします。

私が見たいのは、トランザクションが進行中でも、selectステートメントが一貫したデータで機能することです。スナップショット分離が役立つと思いますが、正しい方向に進んでいるかどうかはわかりません。これは、このアプリケーションに最適な分離レベルでしょうか?

次に、selectステートメントを呼び出しているプロセスを制御することはできませんが、T1を呼び出す.NETアプリケーションを制御します。selectステートメントとT1の両方で分離レベルの変更が必要ですか、それともT1だけを別の分離レベルとしてマークするだけで十分でしょうか?

回答:


8

理想的な世界では、SNAPSHOTとREAD COMMITTED SNAPSHOT(RCSI)の2つの選択肢があります。ワークロードに適したものを決定する前に、トランザクション分離レベルの基本を理解しいることを確認してください。特に、RCSIへの移行の結果として表示されるさまざまな結果に注意してください。

これは、selectステートメントを生成しているアプリケーションを制御できないため、理想的な世界ではないようです。その場合、あなたの唯一のオプションは、selectがREAD COMMITTEDではなくRCSIを自動的に使用するように、問題のデータベースに対してRCSIを有効にすることです。


6

正しい。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を引き続き使用できます。


4

次の質問とその回答を読むことをお勧めします

dbレベルで使用する適切な分離レベルを見つけることは、この問題を解決するために今すぐ実行できる最も速いことです。これは、データベースにアクセスするすべてのアプリケーションを変更してコードを変更することが難しいためです。「selectステートメントを呼び出しているプロセスを制御することはできない」とおっしゃっていたので、最も速い答えは、dbをRead Committed Snapshot分離レベルに切り替えることです。そうすれば、読み取りクエリに触れることはありません。それ以外の場合は、大きなトランザクション中にデータを読み取るセッションにスナップショット分離レベルを使用する必要があります。

正しいものの選択に関する詳細については、行のバージョン管理ベースの分離レベルの選択をご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.