web-dev-qa-db-ja.com

読み取りコミットと反復可能読み取りの違い

上記の分離レベルは似ていると思います。誰かがニースの例を使って主な違いを説明してください。

204
Fore

コミットされた読み取りは、読み取られたデータがcommittedであることを保証する分離レベルです。単に、読者が中間のコミットされていない「ダーティ」な読み取りを見ることを制限します。 ITは、トランザクションが読み取りを再発行した場合、Sameデータが見つかると約束しません。データは、読み取り後に自由に変更できます。

反復可能読み取りはより高い分離レベルであり、読み取りコミットレベルの保証に加えて、すべてのデータ読み取り変更不可を保証します。トランザクションが同じデータを再度読み取る場合、以前に所定の場所で変更されておらず、読み取り可能なデータを読み取りました。

シリアライズ可能な次の分離レベルは、さらに強力な保証を提供します。すべての反復可能な読み取り保証に加えて、nonewdataは、後続の読み取りで確認できます。

たとえば、値が「1」である、1行の列Cを持つテーブルTがあるとします。そして、次のような簡単なタスクがあると考えてください。

BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;

これは、テーブルTから2つの読み取りを発行し、それらの間に1分の遅延がある単純なタスクです。

  • rEAD COMITTEDでは、2番目のSELECTはany dataを返す場合があります。並行トランザクションは、レコードを更新、削除、新しいレコードを挿入する場合があります。 2番目の選択では、常にnewデータが表示されます。
  • rEPEATABLE READでは、2番目のSELECTは最初のselect nchangedで見た行を見ることが保証されています。その1分間に並行トランザクションによって新しい行が追加される場合がありますが、既存の行を削除したり変更したりすることはできません。
  • sERIALIZABLE読み取りでは、2番目の選択でexactlyが最初と同じ行であることが保証されます。並行トランザクションによって行を変更したり、削除したり、新しい行を挿入したりすることはできません。

上記のロジックに従うと、SERIALIZABLEトランザクションは、あなたにとっては楽になりますが、常に完全にブロック可能なすべての同時操作であることにすぐに気付くことができます。任意の行。 .Net System.Transactionsスコープのデフォルトのトランザクション分離レベルはシリアライズ可能です。これは通常、結果のひどいパフォーマンスを説明します。

最後に、SNAPSHOT分離レベルもあります。 SNAPSHOT分離レベルは、シリアライズ可能と同じ保証を行いますが、同時トランザクションがデータを変更できないことを要求するわけではありません。代わりに、すべての読者に世界の独自のバージョン(独自の「スナップショット」)を強制的に表示させます。これにより、同時更新をブロックしないため、非常にスケーラブルであると同時にプログラミングが非常に簡単になります。ただし、その利点には、追加のサーバーリソースの消費という代償が伴います。

補足読み取り:

486
Remus Rusanu

反復可能読み取り

データベースの状態は、トランザクションの開始から維持されます。 session1で値を取得した場合、session2でその値を更新すると、session1で再度取得すると同じ結果が返されます。読み取りは繰り返し可能です。

session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Aaron

コミットを読む

トランザクションのコンテキスト内で、常に最後にコミットされた値を取得します。 session1で値を取得し、session2で値を更新し、session1againで値を取得すると、session2で変更された値が取得されます。最後にコミットされた行を読み取ります。

session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron

session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;

session1> SELECT firstname FROM names WHERE id = 7;
Bob

理にかなっていますか?

59
Hazel_arun

このスレッドに対する私の読みと理解による単純な答えと@ remus-rusanuの答えは、この単純なシナリオに基づいています。

2つのプロセスAとBがあります。プロセスBはテーブルXを読み取っています。プロセスAはテーブルXに書き込んでいます。プロセスBは再びテーブルXを読み取っています。

  • ReadUncommitted:プロセスBはプロセスAからコミットされていないデータを読み取ることができ、Bの書き込みに基づいて異なる行を表示できます。 ロックがまったくない
  • ReadCommitted:プロセスBは、プロセスAからコミットされたデータのみを読み取ることができ、COMMITTED only Bの書き込みに基づいて異なる行を表示できます。 単純ロックと呼べますか?
  • RepeatableRead:プロセスBは、プロセスAが実行しているものと同じデータ(行)を読み取ります。ただし、プロセスAは他の行を変更できます。 行レベルのブロック
  • Serialisable:プロセスBは以前と同じ行を読み取り、プロセスAはテーブルの読み取りまたは書き込みを行えません。 テーブルレベルのブロック
  • スナップショット:すべてのプロセスには独自のコピーがあり、作業中です。 それぞれに独自のビューがあります
19
Mo Zaatar

すでに受け入れられている古い質問ですが、SQL Serverのロック動作をどのように変更するかという観点から、これら2つの分離レベルを考えたいと思います。これは、私がそうであったようにデッドロックをデバッグしている人にとって役立つかもしれません。

READ COMMITTED(デフォルト)

共有ロックはSELECTで取得され、解放されますSELECTステートメントの完了時。これにより、システムは、コミットされていないデータのダーティリードがないことを保証できます。 SELECTが完了した後、トランザクションが完了する前に、他のトランザクションが基になる行を変更する可能性があります。

繰り返し読み取り

共有ロックはSELECTで取得され、解放されますトランザクションが完了した後のみ。これにより、システムは、トランザクション中に読み取り値が変更されないことを保証できます(トランザクションが終了するまでロックされたままになるため)。

12
Chris Gillum

この疑問を簡単な図で説明しようとしています。

Read Committed:この分離レベルでは、トランザクションT1はトランザクションT2によってコミットされたXの更新された値を読み取ります。

Read Committed

繰り返し可能読み取り:この分離レベルでは、トランザクションT1はトランザクションT2によってコミットされた変更を考慮しません。

enter image description here

10
vkrishna17

繰り返し可能な読み取りのrepeatableは、テーブル全体ではなく、タプルに関するものであることに注意してください。 ANSC分離レベルでは、ファントム読み取り異常が発生する可能性があります。つまり、同じwhere句を持つテーブルを2回読み取ると、異なる結果セットが返される可能性があります。文字通り、それは繰り返し可能ではありません。

この写真も役立つと思います。分離レベルの違いをすぐに思い出したいときに参考になります(YouTubeの kudvenkat に感謝)

enter image description here

0
Ivan Pavičić