SET TRANSACTION ISOLATION LEVELの利点はコミットされていません


12

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED私が一般的なSQLクエリの大部分で使用しているのは、主に言語を最初に学習したときにこれがドリルダウンされたためです。

私の理解では、この分離レベルは、WITH (NO LOCK)私が使用する傾向があるのと同じように機能しますSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

  • 私が使用してしなければならないという時間今までありWITH (NO LOCK)オーバーがSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
  • DOESは SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED私が読んでいていることの表からロックアウトされることから、他のユーザーを停止しますか?
  • 場合は SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED、ストップロックに使用されているが、私はデータのみを読んでいます、それを使用してのポイントは何ですか?ロックを生成するのはシステム集中型のクエリだけですか?たとえば5〜10秒で返されるクエリを実行するときに使用する価値はありますか。
  • SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDおそらくダーティデータの更新を避けるために、更新で使用されるデータを読み取るときは使用しないように言わ れました。これが唯一の理由でしょうか?
  • 私が取り組んでいるデータベースのタイプには、実稼働環境とテスト環境があります。実稼働環境にクエリを実行することはほとんどありませんが、必要に応じて、通常SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDはクエリで使用します。これでダーティリードが可能であることを理解しています。最終的にデータベースにコミットされない可能性のあるデータを受信する(そして結果を破棄する)以外に、他の種類の「ダーティリード」は可能ですか?

大量の質問で申し訳ありません。


2
同じデータを2回読み取ることもできます。RUまたはNO LOCKを標準として使用することはお勧めできません。
ジェームズアンダーソン

9
私はREAD UNCOMMITTEDどこでも使用しないのとまったく同じ方法で、WITH (NOLOCK)どこでも使用しません(本質的に同じです)blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
マークシンキンソン

1
SNAPSHOT分離モデルを調べてください。それらはRCUよりも非常に強力であり、ブロックもブロックもしません。それらは、(RCUにデフォルト設定するのではなく!)良いデフォルトモデルのように聞こえます。
usr

回答:


25

そのようにして学んだのは恐ろしいことです(ごめんなさい!)。

READ UNCOMMITTEDはい、すべての行を読みましょう。でも、それらの現在で使用している者INSERTUPDATEDELETE操作。これは、一部のデータをすばやく確認する必要がある場合、またはSELECTブロックが非常に有害なミッションクリティカルなステートメントで非常に便利です。

実際、あなたはあなたの誠実さを危険にさらします。現在削除または変更に使用されている行を読み取ることが発生する場合があります。間違った値を読んだように見えることもあります。これは本当に珍しいことかもしれませんが、起こる可能性があります。それはどういう意味ですか?さて、非常に広い行を考えてみてください(多くの列と長い列がありますnvarchar)。この行で更新が行われ、新しい値が設定されます。まれに、半分の行しか読まないことがあります。たとえば、ユーザーがログイン値を変更した場合など、別のことが起こります。彼はメールとパスワードを変更します。メールは既に設定されていますが、パスワードは設定されていません。これにより、一貫性のない状態になります。

私は忘れることをお勧めしREAD UNCOMMITTEDます。本当に必要な場所で使用してください。

別の方法として、READ_COMMITTED_SNAPSHOTデータベースオプションを有効にすることもできます。したがってREAD COMMITTED SNAPSHOT、tempdbで行のバージョン管理が有効になっているため、使用できます。この方法では、行の別の(古い)バージョンを読み取るだけです。これはクエリをブロックしません。ただし、古い値を読み取ることもありますが、一貫した古い値が読み取られます。

別のアイデアはのWITH(READPAST)代わりになりWITH(NOLOCK)ます。テーブルの古い状態(に少し似てSNAPSHOT ISOLATIONいます)を読み取りますが、代わりに現在ロックされているすべての行をスキップします。


@Ionic、ご回答ありがとうございました!私はその助けに本当に感謝しています。
-dmoney

@HingeSight、それはそのように聞こえますが、声明の私の解釈であった可能性が非常に高い可能性があります、あなたの入力に感謝します。
-dmoney

1
SNAPSHOT ISOLATIONを有効にするために有効にする必要はありませんREAD COMMITTED SNAPSHOTREAD COMMITTED SNAPSHOTデータベースオプションのみを有効にする必要があるため、読み取りの一貫性のためにロックではなく行のバージョン管理が行われ、ダーティリードの必要性が回避されます。
ダン・グスマン

はい、私は@DanGuzmanを意味しました。申し訳ありませんが、その点で答えは少し不明瞭でした。編集しました。:-)
イオン

READPASTを使用すると、ロックされたレコードをスキップします、あなたは古い値を取得することはありません-私はそれを使用することができる考え出した唯一の場所は、キューの処理であるので
ジェームズ・Z

2

受け入れられた答えが述べているように、間違ったデータを読み取るリスクがあるため、READ UNCOMMITTED分離レベルの使用は忘れてください(本当に必要な場合を除く)。しかし、あなたの質問の3番目の箇条書きに答えるために、私が役立つと思う2つの状況があります:

  1. SQL Server SSISパッケージを作成およびテストするとき、パッケージのステップがトランザクションにラップされる場合があります。SSISデバッガーでステップごとに実行してパッケージをテストする場合は、テーブルにロックがかかっているときにテーブルを調べることができます。SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDを使用すると、SQL Server Manager Studioを使用して、パッケージのデバッグ中にテーブルを調べることができます。

  2. SQL Server Manager Studioでは、トランザクションにラップして変更をロールバックするオプションを提供することにより、T-SQLコードをテストできます。たとえば、テストデータベースでは、テストの一環としてデータを初期状態に復元できます。トランザクションラップされたコードをテストしていて、トランザクションの進行中にロックされたテーブルを確認する場合は、SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDを使用して別のウィンドウの値を調べることができます。

これらはREAD UNCOMMITTEDのかなりあいまいな使用法ですが、テスト環境では有用であることがわかりました。


1

ほとんどのデータベースでは、挿入、削除、更新などのアクティビティの大部分は、明示的なトランザクションの外部にあります。

確かに、READ UNCOMMITTED(ダーティリード)はこれらの場合に誤った情報を提供できますが、その情報は5秒前に修正されていました。

ダーティリードが本当に悪い結果を生成するときは、トランザクションが失敗してロールバックする必要があるとき、または明示的なトランザクションを使用して通常一緒に更新される2つのテーブルに対してクエリを実行するときです。

一方、読み取りと書き込みの比率が100(またはそれ以上)である一般的な大規模でビジーなデータベースでは、ダーティリードを使用しないすべての単一(読み取り)クエリは、取得および確認する必要があるため、システムの速度が低下しますロックの場合、およびトランザクションが(通常はデッドロックが原因で)失敗する可能性がはるかに高くなり、より深刻なデータベース整合性の問題が発生する可能性があります。

代わりに、ダーティリードを使用すると、システムの速度と信頼性が向上します(パフォーマンスの改善により、不整合が発生しにくくなります)。

確かに、それらを使用すべきでない場合があります。データベースをデフォルトに設定してREAD UNCOMMITTED分離レベルを使用したりSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED、SQLスクリプトとSPの開始時に明示的なステートメントを使用したりするのは嫌いです。その代わり、(NOLOCK)ヒントはプログラマが自分が何をしているのかを考え、この特定のクエリのこの特定のテーブルではダーティリードは安全であると判断したことを明示しているため、はるかに優れたアプローチです。

ある銀行口座から別の銀行口座に送金するようにアプリケーションをプログラミングしている場合、ダーティリードを使用しないでください。しかし、ほとんどのアプリケーションでは、そのレベルの妄想は必要ありません。

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