TOP 投稿 過去ログ 管理用 RSS RDF

SQLServer「NOLOCKを使用したとき、行の重複や欠落が発生する場合があります」

URL:http://support.microsoft.com/kb/975782/ja
たとえば、次のような状況で行の重複や欠落が発生します。
"READ UNCOMMITTED 分離レベル" で実行されるトランザクションや "NOLOCK ヒント" を使用した読み取りではロックが取得されないため、インデックスをスキャンしている時にページ分割が実行されても、そのページ分割中のページ内の行を読み取ることができます。そして、それらページ内のどの行まで読み取ったか、また、どの行がページ分割により新たなページへ移動されるかが関連し、その行が再び出現するか (重複)、もしくは出現しない (欠落) 可能性があります。

「READ UNCOMMITTED 分離レベル」「NOLOCK」の時、テーブルやレコードに対して読み取り中にロックがかかっていない為、横からデータの操作が加わる恐れがあるとのことです。例として挙げられている現象はレコードを順番に見ているときに、並び順を管理しているツリーに変更が加わって、次のレコードを見てみたら以前と違うなんてことになるみたいです。

同じようにカーソルを開いたまま、ループをゆっくり回してファイル出力や帳票出力を行っていると、レコードが重複したりとかありそうです。

対処方法としては、
 @「NOLOCK」しない。
 A一行ずつなど極短い単位でレコードを取り出す。
 Bレコードセットを取得したらすぐにクローンを取ってDBから分離する。
 C排他のロックを明示的にかける。
などが挙げられます。必要に応じて対応を行いましょう。

…NOLOCKを使用しない場合、対象のレコードに排他ロックがかかっていないかを見て、もしロックされているとそれを待ってしまうようなことがあるような…。しばらく待たされた気がするのですよ。NOLOCKを使うとそれらが無いため速い…速くても抜けているところがあるのですね〜。

文書番号: 975782 - SQL Server で "READ UNCOMMITTED 分離レベル" または "NOLOCK ヒント" を使用した SQL 文を実行してデータを参照すると、読み取ったデータの行が欠落または重複する場合がある

コメント

かすぱ [2009年10月22日(木) 10時15分]
READ UNCOMMITTED……非コミット読み取り。
 コミット前のトランザクションのデータが読めたり、別のトランザクションからデータの挿入・更新・削除が行えてしまう状態。
 デフォルトでは「コミット読み取り」が設定されており、コミットされていないデータは読めません。