回答:
この分離レベルでは、ダーティリードが可能です。1つのトランザクションは、他のトランザクションによって行われたコミットされていない変更を認識する場合があります。
最高レベルの分離を維持するために、DBMSは通常、データのロックを取得するため、同時実行性が失われ、ロックのオーバーヘッドが高くなる可能性があります。この分離レベルは、このプロパティを緩和します。
ウィキペディアの記事でREAD UNCOMMITTED
、いくつかの例と詳細を確認することをお勧めします。
Stack Overflowの初期に彼と彼のチームがデッドロック問題にどのように取り組んだかについてのJeff Atwoodのブログ記事をチェックすることにも興味があるかもしれません。ジェフによると:
しかし、
nolock
危険ですか?で無効なデータを読み取ってしまう可能性がありますread uncommitted
か?はい、理論的には。ACIDの科学を身につけ始めたデータベースアーキテクチャの宇宙飛行士は何も不足していないことに気づくでしょうnolock
。それは本当です:理論は怖いです。しかし、私が考えるのはここにあります。「理論的には理論と実践の間に違いはありません。実際には違いがあります。」私は
nolock
、データベースのデッドロックの問題を解決するために、一般的に「問題がある場合に役立つ」スネークオイルフィックスを使用することはお勧めしません。最初に問題の原因を診断する必要があります。しかし、実際に
nolock
は、絶対にわかっているクエリに追加することが単純で単純な読み取り専用の問題であっても、問題が発生することはないようです。
READ UNCOMMITTED
検討する必要があるレベルの1つの代替手段はですREAD COMMITTED SNAPSHOT
。ジェフをもう一度引用:
スナップショットは、まったく新しいデータ変更追跡方法に依存しています。わずかな論理的な変更ではなく、サーバーがデータを物理的に異なる方法で処理する必要があります。この新しいデータ変更追跡メソッドが有効になると、すべてのデータ変更のコピーまたはスナップショットが作成されます。競合時にライブデータではなくこれらのスナップショットを読み取ることで、読み取り時に共有ロックが不要になり、データベース全体のパフォーマンスが向上する可能性があります。
READ UNCOMMITTED
また、行を2回読み取るか、行全体を見逃す可能性があります。読み取り中にページ分割が発生すると、データのチャンク全体が失われる可能性があります。WITH(NOLOCK)
結果の精度が重要でない場合にのみ使用する必要があります
私のお気に入りの使用例read uncommited
は、トランザクション内で発生している何かをデバッグすることです。
デバッガーの下でソフトウェアを起動します。コード行をステップ実行している間、トランザクションが開き、データベースが変更されます。コードが停止している間、クエリアナライザーを開いて、コミットされていない読み取りの分離レベルを設定し、クエリを実行して何が起こっているかを確認できます。
また、これを使用して、長時間実行されているプロシージャがスタックしているか、またはデータベースを正しく更新しているかどうかを確認することもできます。
あなたの会社が過度に複雑なストアドプロシージャを作成することを愛するなら、それは素晴らしいことです。
利点は、状況によってはより高速になる可能性があることです。欠点は、結果が間違っている可能性があり(まだコミットされていないデータが返される可能性があります)、結果が再現可能である保証はありません。
精度を気にする場合は、使用しないでください。
詳細はMSDNにあります:
ダーティリード、または分離レベル0のロックを実装します。つまり、共有ロックは発行されず、排他ロックは適用されません。このオプションを設定すると、コミットされていないデータやダーティデータを読み取ることができます。トランザクションが終了する前に、データの値を変更したり、データセット内の行を表示または非表示にしたりできます。このオプションは、トランザクションのすべてのSELECTステートメントのすべてのテーブルにNOLOCKを設定するのと同じ効果があります。これは、4つの分離レベルの中で最も制限が少ないものです。
select
ステートメントは、他のトランザクションによって排他的にロックされているリソースの共有ロックを取得するために待機する必要はありません。
いつ使用しても大丈夫READ UNCOMMITTED
ですか?
良い:常に変化する合計を示す大きな集計レポート。
危険:ほとんどすべて。
朗報は、読み取り専用レポートの大部分がそのグッドカテゴリに分類されることです。
それを使用してOK:
これはおそらく、ビジネスインテリジェンス部門がSSRSなどで行うことの大部分をカバーしています。もちろん例外は、その前に$記号があるものです。多くの人々は、顧客にサービスを提供し、そのお金を生成するために必要な関連するコア指標に適用されるよりもはるかに熱心にお金を占めています。(私は会計士のせいです)。
危険なとき
詳細レベルに至るレポート。その詳細が必要な場合は、通常、すべての行が決定に関連していることを意味します。実際、ブロックせずに小さなサブセットをプルできない場合は、それが現在編集されているという正当な理由がある可能性があります。
歴史的なデータ。実用的な違いが生じることはめったにありませんが、ユーザーは絶えず変化するデータは完璧ではないことを理解していますが、静的データについては同じとは感じていません。ダーティリードはここでは害にはなりませんが、ダブルリードが時々害を及ぼす可能性があります。とにかく静的データをブロックすべきではないのに、なぜそれを危険にさらすのでしょうか。
書き込み機能も備えたアプリケーションに供給するほとんどすべてのもの。
OKシナリオでもOKでない場合。
NOLOCK
、これらのテーブルでは何も使用できません。read uncommitted
、データの精度がそれほど重要ではないUIグリッドをユーザーが表示するときに、Webアプリケーションに使用するべきかどうかです。ユーザーは、レコードが何であるかを簡単に確認したいだけで、ページング、並べ替え、およびフィルタリングが必要な場合があります。ユーザーが[編集]ボタンをクリックしたときのみ、より厳密な分離レベルで最新のレコードを読み取ろうとします。このようなアプローチはパフォーマンスの点で優れていると思いませんか?
select item from things with (UPDLOCK)
ます。そこにクイックタイムアウトを設定して、ロックをすばやく取得できない場合に、編集中であることをユーザーに通知します。これにより、ユーザーだけでなく開発者からも安全に保つことができます。ここで問題になるのは、タイムアウトと、UIでのタイムアウトの処理方法について考え始める必要があることだけです。
レポートに関しては、すべてのレポートクエリで使用して、クエリがデータベースを停止させないようにします。マイクロ秒までのデータではなく、履歴データを取得しているので、それが可能です。
ソースが変更される可能性が非常に低い状況では、READ_UNCOMMITTEDを使用します。
フェッチ操作中にソースが変更される可能性があることがわかっている場合は、READ_UNCOMMITTEDを使用しないでください。
READ UNCOMMITTED
ます。
READ UNCOMMITTED
ます。データがアクティブに使用されており、不注意に悪用しているユーザーがいるだけでデッドロックやトランザクションのロールバックの可能性を回避するためにサーバーの負荷を軽減したい場合に、ほとんどのメリットを享受できます。データグリッドのあるWebページの[更新]ボタン。多数のレコードを同時に表示するユーザーは、通常、データが少し古いか部分的に更新されているかどうかはあまり気にしません。ユーザーがレコードを編集しようとしているときのみ、最も正確なデータを提供することができます。
これにより、ダーティリードが得られ、まだコミットされていないトランザクションが表示されます。それが最も明白な答えです。読み取り速度を上げるためだけにこれを使用するのは良い考えではないと思います。優れたデータベース設計を使用する場合、他の方法でこれを行うことができます。
何が起こっていないかを指摘することも興味深いです。READ UNCOMMITTEDは、他のテーブルロックを無視するだけではありません。それ自体もロックを引き起こしていません。
大きなレポートを生成している場合、または大きくて複雑な可能性のあるSELECTステートメントを使用してデータベースからデータを移行している場合を考えてください。これにより、トランザクション中に共有ロックがエスカレートされる可能性があります。他のトランザクションはテーブルから読み取ることができますが、更新は不可能です。プロダクションが完全に停止する可能性があるため、プロダクションデータベースの場合、これは悪い考えかもしれません。
READ UNCOMMITTEDを使用している場合、テーブルに共有ロックを設定しません。いくつかの新しいトランザクションから結果を取得するか、データが挿入されたテーブルの場所やSELECTトランザクションが読み取った時間に依存しない場合があります。たとえばページ分割が発生した場合、同じデータが2回取得される場合もあります(データはデータファイル内の別の場所にコピーされます)。
したがって、SELECTの実行中にデータを挿入できることが非常に重要な場合は、READ UNCOMMITTEDが意味をなす場合があります。レポートにはいくつかのエラーが含まれる可能性があることを考慮する必要がありますが、数百万の行に基づいており、結果の選択中に更新されるのがほんの数行である場合、これで十分です。行の一意性が保証されない場合があるため、トランザクションがすべて失敗することもあります。
全体としては、SNAPSHOT ISOLATION LEVELを使用することをお勧めしますが、これを使用するには、アプリケーションでいくつかの調整が必要になる場合があります。この1つの例は、アプリケーションが行を排他的にロックして、他のユーザーが行を読み取らないようにし、UIで編集モードに入る場合です。SNAPSHOT ISOLATION LEVELには、パフォーマンスがかなり低下します(特にディスク上)。しかし、問題にハードウェアを投入することでそれを克服することができます。:)
データウェアハウスへのデータのレポートまたはロードに使用するデータベースのバックアップを復元することも検討できます。
今は常にREAD UNCOMMITTEDを使用しています。問題が少なく、高速です。他の分離を使用すると、ほとんどの場合、いくつかのブロッキングの問題に遭遇します。
自動インクリメントフィールドを使用し、挿入にもう少し注意を払う限り、罰金を科せば、問題をブロックするのに別れを告げることができます。
READ UNCOMMITEDを使用するとエラーが発生する可能性がありますが、正直に言うと、挿入が完全であることを確認するのは非常に簡単です。選択からの結果を使用する挿入/更新は、注意する必要がある唯一のものです。(ここでREAD COMMITTEDを使用するか、ダーティーリードが問題を引き起こさないことを確認してください)
Dirty Reads(特に大きなレポートの場合)を実行すると、ソフトウェアがよりスムーズに実行されます...
Committed
が挿入と更新に切り替えることを明確にしました。他の問題については、自動インクリメントキーの使用について言及する際に、ページ分割の問題を認識していることも示しました。人間だけで読まれるように作成されたほぼすべてのライブレポートは、最終的な小数点以下のわずかな差異を許容できると彼は同意します。機械で読み取って変換する予定の詳細なリストやデータについては別の話であり、Cliveもそうだと思います。