ホームページ  >  記事  >  データベース  >  ダーティ リード、ファントム リード、非反復読み取り、および失われた更新インスタンス

ダーティ リード、ファントム リード、非反復読み取り、および失われた更新インスタンス

PHP中文网
PHP中文网オリジナル
2017-06-21 15:55:552559ブラウズ

2017年6月5日、天気は雨。

2 日前、以前の学習ノートを整理していたとき、トランザクションの同時実行によって引き起こされる問題について、ダーティ リード、ファントム リード、非反復可能リード、ロスト アップデートの概念が少し曖昧だったので、見直してみました。もう一度、私自身の一部を載せます。全員の学習を促進するために、理解を次のように要約して整理します。

ロックは、他のトランザクションが指定されたリソースにアクセスするのを防ぐ手段です。ロックは同時実行制御を実現する主な方法であり、複数のユーザーがデータの不整合を生じることなく同じデータベース内のデータを同時に操作できることを保証する重要な手段です。 一般に、ロックはダーティ読み取り、反復不能読み取り、およびファントム読み取りを防止します。

1.ダーティリード——トランザクションは、別のトランザクションがコミットしていないデータを読み取ります。

詳細な説明: トランザクションがデータにアクセスしてデータを変更しているが、その変更がまだデータベースに送信されていない場合、別のトランザクションもデータにアクセスし、そのデータを使用します。このデータはまだコミットされていないため、別のトランザクションによって読み取られたデータはダーティ データであり、ダーティ データに基づく操作は正しくない可能性があります。

トランザクション T1: データの一部を更新します
トランザクション T1 のダーティ データと呼ばれるこのプロセスは、ダーティ リーディングと呼ばれます。

ダーティ リードは、あるトランザクション A が、別のトランザクション B によって変更されたがまだコミットされていないデータを読み取るときに発生します。 B がロールバックすると、トランザクション A は無効なデータを読み取ります。これは反復不可能な読み取りに似ていますが、2 番目のトランザクションをコミットする必要はありません。

ダーティ読み取りの問題を解決します。変更時に排他ロックを追加し、トランザクションがコミットされるまで解放します。読み取り後に、トランザクション 1 を解放し、データの読み取り時に共有ロックを追加します。データの読み取り (プロセス中、他のトランザクションはデータを変更しません)、トランザクションはデータに対する操作を許可されず、後で更新操作がある場合は読み取りのみが可能であり、他のトランザクションは排他ロックに変換されます。には読み取りと書き込みに参加する権利がないため、ダーティ リードの問題が回避されます。ただし、トランザクション 1 がデータを読み取っている場合、読み取りが完了した後、他のトランザクションもデータを読み取っている可能性があります。このとき、トランザクション 1 は、変更が完了した後にデータを変更します。トランザクションが送信されると、他のトランザクションがデータを再度読み取るときに、データが矛盾している場合、非反復読み取りの問題が発生するため、非反復読み取りの問題を回避できません。

2.

Phantom

)——同じトランザクション内で、同じ操作で2回読み取りが行われ、取得されるレコード数が異なります。 詳細説明: ファントム読み取りとは、トランザクションが独立して実行されない場合に発生する現象を指します。たとえば、最初のトランザクションがテーブル内のデータを変更し、この変更にはテーブル内のすべてのデータ行が含まれます。同時に、2 番目のトランザクションもこのテーブルのデータを変更します。この変更により、テーブルに新しいデータの行が挿入されます。その後、最初のトランザクションを操作するユーザーは、あたかも幻覚が起こったかのように、テーブル内にまだ変更されていないデータ行が存在することに気づくでしょう。

トランザクション T1: テーブル内のすべてのレコードをクエリします

これはファントム読み取りと呼ばれます。



注: ファントム リーディングの焦点は追加または削除です。


ファントム読み取りは、2 つの同一のクエリが実行され、2 番目のクエリによって返される結果セットが最初のクエリと異なる場合に発生します。

何が起こるか: スコープはロックされません。

回避方法: シリアル化分離モードの実装は、低レベルの分離で発生する可能性があります。

ファントム読み取り問題の解決: 範囲ロック RangeS RangeS_S モードは、検索範囲を読み取り専用としてロックするために使用され、ファントム読み取り問題を回避します。 3.

Nonrepeatable Read

——同じトランザクション内で、同じデータが 2 回読み取られ、内容が異なります。询 業務 T1: レコードのクエリ

-& gt; トランザクション T2: トランザクション T1 のクエリ レコードの更新

-& gt; トランザクション T2: トランザクション T1 の送信のコミットの呼び出し

このとき、トランザクション T1 T1 は同じデータは 2 回クエリされますが、利用可能なコンテンツは異なります。これは、非反復読み取りと呼ばれます。

注: 反復不可能な読み取りでは、変更に重点が置かれます。


ロックベースの並列制御方式では、select実行時にリードロックを付加しないと、Non-Repeatable Readの問題が発生します。

マルチバージョン並列制御メカニズムでは、コミット競合が発生したトランザクションをロールバックする必要があるにもかかわらず解放されると、反復不可能な読み取りの問題が発生します。

この問題の発生を防ぐには 2 つの戦略があります:

(1) トランザクション 1 がコミットまたはロールバックされるまでトランザクション 2 の実行を遅らせます。この戦略は、ロックを使用する場合に適用されます。

(2) マルチバージョン並列制御では、トランザクション 2 を最初に送信し、トランザクション 1 が古いバージョンのデータで実行を継続することができます。最後にトランザクション 1 がコミットしようとすると、データベースはその結果がトランザクション 1 とトランザクション 2 が連続して実行されたときと同じかどうかを確認します。 「はい」の場合、トランザクション 1 は正常に送信されます。そうでない場合、トランザクション 1 はロールバックされます。

反復不可能な読み取りの問題を解決します。データを読み取るときに共有ロックを追加し、データを書き込むときに排他的ロックを追加し、トランザクションの送信後にのみロックを解放します。読み取り時にデータを変更することは許可されていません。トランザクション中にデータが何度読み取られても、データは一貫しているため、読み取りが繰り返されないという問題が回避されます。
4.Lost Update(Lost Update)

トランザクション T1 はデータを読み取り、いくつかの操作を実行してから、データを更新します。トランザクション T2 も同じことを行うため、T1 と T2 がデータを更新すると、互いの更新を上書きしてエラーが発生する可能性があります。

5. 上記の分離レベルの問題に対処するには、次の方法を使用します:

5 つのトランザクション分離レベル:
(1) TRANSACTION_NONE はトランザクションを使用しません。
(2) TRANSACTION_READ_UNCOMMITTED はダーティ リードを許可します。
(3) TRANSACTION_READ_COMMITTED は、最も一般的に使用される分離レベルであるダーティ リードを防止し、ほとんどのデータベースのデフォルトの分離レベルです。
(4) TRANSACTION_REPEATABLE_READ は、ダーティ リードと反復不可能な読み取りを防ぐことができます。
(5) TRANSACTION_SERIALIZABLE は、データベースの効率を低下させるダーティ リード、反復不可能な読み取り、ファントム リードを防止できます。

上記の 5 つのトランザクション分離レベルは、Connection インターフェイスで定義された静的定数であり、setTransactionIsolation(int level) メソッドを使用してトランザクション分離レベルを設定します。

例: con.setTransactionIsolation(Connection.REPEATABLE_READ)。

注: トランザクションの分離レベルはデータベースによって制限されます。異なるデータベースでサポートされる分離レベルは必ずしも同じではありません。

以上がダーティ リード、ファントム リード、非反復読み取り、および失われた更新インスタンスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。