(ターン)MySQL分離レベルの深い理解

転送元:https://www.jianshu.com/p/8d735db9c2c0

トランザクションとは

トランザクションは、アプリケーションでの一連の厳密な操作です。すべての操作を正常に完了する必要があります。そうしないと、各操作のすべての変更がキャンセルされます。つまり、トランザクションはアトミックであり、トランザクション内の一連の操作はすべて成功するか、まったく実行されません。

トランザクションの終了には2つのタイプがあります。トランザクションのすべてのステップが正常に実行されると、トランザクションはコミットされます。ステップの1つが失敗すると、ロールバック操作が発生し、トランザクションの前から開始までのすべての操作が取り消されます。

トランザクションのACID

トランザクションには、原子性、一貫性、分離性、耐久性の4つの特性があります。これらの4つの機能は、略してACID機能と呼ばれます。

Atomicity:トランザクションは、データベースの論理的な作業単位です。トランザクションに含まれるすべての操作は、実行されるか実行されないかのいずれかです。

一貫性:トランザクション実行の結果は、データベースをある一貫性のある状態から別の一貫性のある状態に変更する必要があります。したがって、データベースにトランザクション送信の成功の結果のみが含まれている場合、データベースは一貫性のある状態にあると言われます。

分離:1つのトランザクションと他のトランザクションの間に干渉はありません。

永続性:トランザクションがコミットされると、データベース内のデータへの変更は永続的である必要があります。以下の他の操作または失敗は、他の実行結果に影響を与えるべきではありません。

Mysqlの4つの分離レベル

SQL標準では、トランザクションの内部と外部のどの変更を表示し、どの変更を非表示にするかを制限する特定のルールとルールを含む、4種類の分離レベルを定義しています。低レベルの分離レベルは、通常、より高い同時処理
サポートし、システムオーバーヘッドが低くなります。

Uncommittedを読む(コミットされていないコンテンツを読む)

この分離レベルでは、すべてのトランザクションが他のコミットされていないトランザクションの実行結果を確認できます。この分離レベルは、パフォーマンスが他のレベルよりもはるかに優れていないため、アプリケーションの実装に使用されることはめったにありません。コミットされていないデータの読み取りは、ダーティ読み取りとも呼ばれます。

コミット済みを読む(提出されたコンテンツを読む)

これは、ほとんどのデータベースシステムのデフォルトの分離レベルです(ただし、mysqlのデフォルトではありません)。これは、分離の単純な定義を満たします。トランザクションは、コミットされたトランザクションによって行われた変更のみを確認できます。この分離レベルは、いわゆる繰り返し不可の読み取りもサポートします。これは、同じトランザクションの他のインスタンスがインスタンスの処理中に新しいコミットを持っている可能性があるため、同じ選択が異なる結果を返す可能性があるためです。

繰り返し読み取り

これはMySQLのデフォルトのトランザクション分離レベルであり、データを同時に読み取るときに、同じトランザクションの複数のインスタンスに同じデータ行が表示されるようにします。しかし、理論的には、これは別のトリッキーな問題、ファントムリーディングにつながります。簡単に言うと、ファントム読み取りとは、ユーザーが特定の範囲のデータ行を読み取ると、別のトランザクションがその範囲に新しい行を挿入し、ユーザーが特定の範囲のデータ行を読み取ると、別のトランザクションが同じ範囲にあることを意味します。範囲内に新しい行が挿入されます。ユーザーが範囲内のデータ行を再度読み取ると、新しいファントム行が見つかります。

シリアル化可能(シリアル化可能)

これは最高の分離レベルであり、トランザクションを強制的に相互に競合させないようにすることで、ファントム読み取りの問題を解決します。つまり、各読み取りデータ行に共有ロックを追加することです。これが数回発生すると、多くのタイムアウトやロックの競合が発生する可能性があります。

これらの4つの分離レベルは、異なるロックタイプを使用して実装されます。同じデータが読み取られると、次のような問題が発生しやすくなります。

ダーティリード:トランザクションがデータを更新し、別のトランザクションがこの時点で同じデータを読み取ります。何らかの理由で、前のロールバック操作が実行され、次のトランザクションによって読み取られたデータが正しくありません。の。

繰り返し不可の読み取り:トランザクションの2つのクエリでデータに一貫性がありません。これは、2つのクエリの間に挿入されたトランザクションによって更新された元のデータである可能性があります。

ファントム読み取り:トランザクションの2つのクエリでデータに一貫性がありません。たとえば、1つのトランザクションが複数の列のデータをクエリし、別のトランザクションがこの時点で新しい列のデータを挿入します。前のトランザクションは次のクエリにあります。クエリされていないデータの列がいくつかあります。この時点でデータを挿入し、別のトランザクションを挿入すると、エラーが報告されます。
ここに写真の説明を挿入

Mysqlの分離レベルをテストします

次に、MYSQLクライアントプログラムを使用してこれらの分離レベルをテストします。
テストデータベースはデモであり、テーブル構造です
ここに写真の説明を挿入
。2つのコマンドラインクライアントはそれぞれAとBです。Aの分離レベルを常に変更し、B側のデータを変更します

Aの分離レベルをコミットされていない読み取り(コミットされていない読み取り)に設定します

ここに写真の説明を挿入

A:トランザクションを開始します。この時点でデータは初期状態です
ここに写真の説明を挿入
。B:トランザクションを開始し、データを更新しますが、送信しないで
ここに写真の説明を挿入
ください。A:データを再度読み取り、データが変更されていることを確認します。これはいわゆる「ダーティリード」です
ここに写真の説明を挿入
。B:トランザクションをロールバックします
ここに写真の説明を挿入
。A :データを再度読み取り、データが初期状態に戻ったことを確認します。
ここに写真の説明を挿入
上記の実験の後、トランザクションBはレコードを更新したが送信されなかったと結論付けることができます。この時点で、トランザクションAはコミットされていないレコードを照会できます。汚れた読み取り現象を引き起こします。コミットされていない読み取りは、最低の分離レベルです。

クライアントAのトランザクション分離レベルを読み取りコミット(読み取りコミット)に設定します

ここに写真の説明を挿入
A:トランザクションを開始します。この時点でデータは初期状態です
ここに写真の説明を挿入
。B:トランザクションを開始し、データを更新しますが、送信しないで
ここに写真の説明を挿入
ください。A:データを再度読み取り、データが変更されていないことを確認してください
ここに写真の説明を挿入
。B:トランザクションを送信して
ここに写真の説明を挿入
ください。A:データを再度読み取り、データが変更されていることを確認してください。 Bによって送信された変更がトランザクションでAによって読み取られたことを説明します。これは、いわゆる「繰り返し不可の読み取り」です。
ここに写真の説明を挿入
上記の実験の結果、送信された読み取り分離レベルはダーティ読み取りの問題を解決すると結論付けることができますが、繰り返し不可能な読み取りがあります。問題は、トランザクションBが2つのクエリ間でデータの一部を更新したため、トランザクションAのデータが2つのクエリで一貫していないことです。送信された読み取りは、送信されたレコードの読み取りのみが許可されますが、繰り返し読み取る必要はありません。

Aの分離レベルを繰り返し可能読み取り(繰り返し可能読み取り)に設定します

ここに写真の説明を挿入
A:トランザクションを開始します。この時点でデータは初期状態です
ここに写真の説明を挿入
。B:トランザクションを開始し、データを更新しますが、送信しません
ここに写真の説明を挿入
。A:データを再度読み取り、データが変更されていないことを確認します
ここに写真の説明を挿入
。B:トランザクションを送信します
ここに写真の説明を挿入
。A:データを再度読み取り、データがまだ発生していないことを確認します。変更。つまり、今回は
ここに写真の説明を挿入
B:新しいデータを挿入し、送信することができます
ここに写真の説明を挿入
。A:データを再度読み取ります。読み取りを繰り返すことはできますが、データは変更されていないことがわかりますが、読み取りは最新のデータではないことがわかります。これはいわゆる「ファントムリーディング」です
ここに写真の説明を挿入
。A:このトランザクションを送信し、データを再度読み取り、読み取りが正常であることを確認します。
ここに写真の説明を挿入

Aの分離レベルをSerializable(Serializable)に設定します

ここに写真の説明を挿入
A:トランザクションを開始します。データはこの時点での初期状態です。

ここに写真の説明を挿入
B:Aのトランザクションはまだ送信されておらず、待機することしかできないため、この時点でBが待機状態になっていることがわかります(この時点で、Bには待機タイムアウトがある可能性があります)
ここに写真の説明を挿入
A:トランザクションを送信します
ここに写真の説明を挿入
B:挿入が成功し、
ここに写真の説明を挿入
シリアル化可能でフィールドが完全にロックされていることがわかります。同じデータを照会するトランザクションは、前のトランザクションが完了してロックが解除されるまで待機する必要があります。これは完全な分離レベルであり、対応するデータテーブルがロックされるため、効率の問題が発生します。

おすすめ

転載: blog.csdn.net/weixin_46011971/article/details/108913646