ホームページ > データベース > mysql チュートリアル > データベース トランザクション分離レベルとダーティ リード、非反復読み取り、ファントム リードを理解する方法

データベース トランザクション分離レベルとダーティ リード、非反復読み取り、ファントム リードを理解する方法

坏嘻嘻
リリース: 2018-09-15 11:36:36
オリジナル
3147 人が閲覧しました

この記事は、データベース トランザクションの分離レベルとダーティ リード、ノンリピータブル リード、ファントム リードを理解する方法について説明しています。必要な方は参考にしていただければ幸いです。あなたのお役に立てますように。

1. データベース トランザクションを正しく実行するための 4 つの基本要素

1.1ACID の原則。

ACID 原則は、データベース トランザクションを通常に実行するための 4 つの基本要素であり、原子性、一貫性、独立性、耐久性を指します。

トランザクションのアトミック性 (アトミシティ)とは、トランザクションが完全に実行されるか、または実行されないことを意味します。つまり、トランザクションは途中でのみ実行され、その後停止することはできません。マシンからお金を引き出すには、この取引は 2 つのステップに分けることができます: 1. カードをスワイプする、2. お金を引き出す。カードをスワイプしてもお金が出てこないということはありません。これらの 2 つのステップを同時に完了する必要があります。さもなければ、まったく完了しません。

トランザクションの一貫性 (一貫性)とは、トランザクションの操作によってデータベース内のデータの一貫性が変化しないことを意味します。たとえば、整合性制約 a b=10 の場合、トランザクションによって a が変更されると、それに応じて b も変更される必要があります。つまり、AがBに300元を送金する場合、Aの口座は300元減らされ、Bの口座は200元増加するなどの増減とは言えません。これはトランザクションのアトミック性とは一致しますが、トランザクションの一貫性とは一致しません。実際のビジネスでは、設計上の欠陥により、メインテーブルに在庫があり、在庫テーブルに在庫があり、在庫を差し引くのと同じようなロジックになることがよくあります。 、トランザクションが追加されても、売られすぎやSKU在庫が総在庫と一致しない問題に加えて、一貫性が満たされていないことが表示されます。

独立性(分離): トランザクションの独立性は分離とも呼ばれ、データの不整合が生じる可能性があるため、複数のトランザクションがインターリーブされた状態で実行されないことを意味します。 。

永続性(耐久性): トランザクションがコミットまたはロールバックされると、分離によって発生する可能性のある読み取り問題に関係なく、この状態をデータベースに永続化する必要があります。


1.2 ダーティ リーディング、再現不可能なリーディング、ファントム リーディング。

Dirty read (ダーティリード): あるトランザクション内で、別のトランザクションによってコミットされていないデータを読み取ること。たとえば、トランザクションがデータにアクセスしてデータを変更したが、その変更がまだデータベースにコミットされていない場合、別のトランザクションもデータにアクセスし、そのデータを使用します。

Non-repeatable read(Non-Repeatable Read): どちらも同じデータ内容を読み取ることはできません。これは、トランザクションが終了する前に、最初のトランザクションの 2 回のデータ読み取りの間に、同じデータが複数回読み取られることを意味します。これは、2 つのトランザクション間の変更のためです。トランザクションの場合、最初のトランザクションで 2 回読み取られたデータは異なる場合があります。

Phantom Read(ファントム読み取り): トランザクション内で、2 つのクエリの結果が矛盾しています (挿入操作の場合)。これは、トランザクションが独立して実行されない場合に発生する現象を指します。たとえば、最初のトランザクションがテーブル内のデータを変更し、この変更にはテーブル内のすべてのデータ行が含まれます。同時に、2 番目のトランザクションもこのテーブルのデータを変更します。この変更により、テーブルに新しいデータの行が挿入されます。その後、最初のトランザクションを操作するユーザーが、テーブル内にまだ変更されていないデータ行が存在することに気付いた場合、それは錯覚のようなものになります。
たとえば、編集者が作成者によって送信されたドキュメントを変更しますが、プロダクションがその変更をドキュメントのマスター コピーにマージすると、作成者が新しい未編集の内容をドキュメントに追加したことがわかります。この問題は、編集者と制作部門が元のドキュメントの作業を完了するまで、誰もドキュメントに新しい内容を追加できないようにすれば回避できます。


2. データベース トランザクション分離レベル

データベース トランザクションには 4 つの分離レベルがあり、低から高まで、読み取り非コミット (コミットされていない読み取り)、コミット済み読み取り (コミット済み読み取り) です。リピータブルリード(反復可能読み取り)、シリアライザブル(シリアル化)、これら4つのレベルは、ダーティリード、ノンリピータブルリード、ファントムリードの問題を一つずつ解決できます。

2.1 非コミットを読む

会社は賃金を支払い、リーダーはシンゴの口座に 5,000 元を送金しましたが、シンゴが彼の口座を確認したところ、その取引はたまたま送信されておらず、彼の給料が5,000元であることがわかり、彼はとても幸せでした。残念ながら、リーダーは、singo に支払われる給与が 2,000 元である必要があることに気づき、すぐにトランザクションをロールバックし (5,000 元をロールバック)、金額を変更し (2,000 元に)、最後に、singo に実際の給与を送信しました。たったの2,000元で、シンゴさんは幸せです。

上記の状況が発生します。これはダーティ リーディングと呼ばれるもので、2 つの同時トランザクション、「トランザクション A: リーダーが singo に給与を支払う」、「トランザクション B: singo が給与口座をクエリする」、トランザクション B がトランザクションを読み取ります。 A はまだデータをコミットしていません。

分離レベルが Read uncommitted (read uncommitted) に設定されている場合、ダーティ リードが発生する可能性があります。このときに分離レベルを Read commit (read commited) に上げると、ダーティ リードを回避できます。


#2.2 コミット済みの読み取り

シンゴさんは買い物をするために給与カードを受け取りましたが、システムはカードに確かに 2,000 元があることを読み取りました。このとき、彼女の妻はたまたまオンラインで送金しており、シンゴさんの給与から 2,000 元を送金しました。カードを別の口座に移し、以前、singo で取引を提出しましたが、singo がお金を差し引くときに、システムは、singo の給与カードにお金がないことを確認し、singo は明らかにお金が入っていたため、引き落としに失敗しました。カードだけど、どうなったの?

上記の状況が発生します。つまり、非反復読み取りと呼ばれるもので、2 つのトランザクションが同時に実行されます。「トランザクション A: singo の消費」、「トランザクション B: singo の妻のオンライン転送」、トランザクション A が事前に読み取っています。データ、トランザクション B はすぐにデータを更新してトランザクションをコミットし、トランザクション A が再度データを読み取ると、データは変更されていました。

分離レベルを Read commit に設定すると、ダーティ リードは回避されますが、非反復読み取り(同じデータ内容を読み取れない)が発生する可能性があります。

SQL Server や Oracle など、ほとんどのデータベースのデフォルト レベルは読み取りコミットです。現時点では、分離レベルを反復読み取りにアップグレードすると、ダーティ リードや非反復読み取りの発生を回避できます。 。


2.3 反復読み取り

- 分離レベルが反復読み取りに設定されている場合、非反復読み取りを回避できます。 singo さんが給与カードを消費するために受け取った場合、システムが給与カード情報の読み取りを開始すると (つまり、取引が開始されます)、singo の妻は記録を変更できません。つまり、singo の妻はこの時点では送金できません。

(ここでの 2 つのブログの例は異なります。理由を示してください) つまり、セッション A とセッション B が 2 つあり、それぞれ 2 つのトランザクションが開かれ、 A は B に 500 元を転送するメッセージを送信し、A がトランザクションを送信し、B が再度確認したところ、元の金額であることがわかりました。B は現在のトランザクションを終了して、データの変更をクエリする新しいトランザクションを開始することしかできないため、変更を回避できます。 -反復可能な読み取り。 Seriizable (シリアル化) を設定すると、テーブルをロックすることと同じになり、ある時点で 1 つのトランザクションのみがテーブルにアクセスできます。

リピータブルリードは非リピータブルリードを回避しますが、ファントムリードは依然として発生する可能性があります。

たとえば、Singo の妻は銀行部門で働いており、銀行の内部システムを通じて Singo のクレジット カードの使用記録を頻繁にチェックします。ある日、彼女はその月のシンゴのクレジットカードの合計使用額(月=今月の取引から合計(金額)を選択)が80元であることを確認していました。このとき、シンゴはたまたま外で食事をし、請求書を支払いました。レジで 1,000 元、つまり 1,000 元の新しい消費記録 (取引を挿入...) を追加し、その取引を提出しました。その後、singo の妻は、その月の singo のクレジット カードの使用明細を A4 用紙に印刷しました。しかし、合計消費額が 1,080 元であることに気づき、妻は非常に驚き、幻覚が起こったのだと思いました。

注: Mysql のデフォルトの分離レベルは反復読み取りです。


2.4 Serializable
Serializable は最も高いトランザクション分離レベルですが、最も高価であり、現時点ではほとんど使用されません。このレベルでは、トランザクションは順次実行され、ダーティ リードや反復不可能な読み取りを回避するだけでなく、ファントム リードも回避します。


3. 概要

3.1 分離レベルとそれに対応する考えられる問題の表

分離レベル ダーティ リード NonRepeatable Read ファントム リード
コミットされていない読み取り(コミットされていない読み取り) おそらく おそらく おそらく
コミットされた読み取り(コミットされた読み取り) 不可能 可能 可能
繰り返し読み取り(繰り返し読み取り) 不可能 不可能 可能
シリアル化(シリアル化可能) 不可能 不可能######不可能############

以上がデータベース トランザクション分離レベルとダーティ リード、非反復読み取り、ファントム リードを理解する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート