トランザクション分離レベルは 4 つあります。 1. コミットされていない読み取り (コミットされていない読み取り)。コミットされていないデータ変更の読み取りを許可します。これにより、ダーティ リード、反復不可能な読み取り、およびファントム読み取りが発生する可能性があります。 2. Read Committed (Read Committed) では、同時トランザクションによって送信されたデータを読み取ることができます。これによりダーティ リードを回避できますが、反復不可能なファントム リードが発生する可能性があります。 3.Repeatable Read (反復可能読み取り)、同じフィールドの複数の読み取りの結果は一貫しています。 4. シリアル化可能 (シリアル化可能)。
このチュートリアルの動作環境: Windows7 システム、mysql8 バージョン、Dell G3 コンピューター。
#1. トランザクションとは何ですか?
トランザクションは一連の論理的な操作であり、すべての操作が実行されるか、まったく実行されないかのどちらかです。
不倫で最も古典的でよく言われるのが銀行振込です。たとえば、シャオミンがシャオホンに 1,000 元を送金したい場合、この送金には 2 つの重要な操作が必要になります。シャオミンの残高を 1,000 元減らすことと、シャオホンの残高を 1,000 元減らすことです。これら 2 つの操作の間に突然エラーが発生し、Xiao Ming の残高が減少する一方、Xiao Hon の残高が増加しない場合、この状況は絶対に許可されません。トランザクションは、これら 2 つの主要な操作が成功するか、どちらも成功しないかを確認することです。
2. トランザクション特性 (ACID)
- **原子性:* *トランザクションの最小実行単位であるため、分割は許可されません。トランザクションのアトミック性により、アクションがすべて実行されるか、まったく実行されないかのいずれかが保証されます。
- **一貫性:**トランザクションの実行前と実行後、データの一貫性が維持されます。例えば、送金ビジネスでは、取引が成功しても失敗しても、送金者と受取人の合計金額は変わらないはずです。
- **分離:**データベースに同時にアクセスする場合、ユーザーのトランザクションは他のトランザクションの影響を受けないようにする必要があり、データベースは同時トランザクション間で独立しています。
- **永続性:**トランザクションがコミットされた後、データベース内のデータに対する変更は永続的であり、データベースに障害が発生した場合でも影響を受けません。
3. 同時トランザクションによって引き起こされる問題
典型的なアプリケーションでは、複数のトランザクションが同時に実行され、同じデータを操作して目的を達成することがよくあります。それぞれのタスクを完了します (複数のユーザーが同じデータを操作します)。同時実行性は必要ですが、次の問題が発生する可能性があります:
- **ダーティ リード: **トランザクションがデータにアクセスし、それを変更したが、まだトランザクションが送信されなかった場合。今回は、別のトランザクションもデータにアクセスし、そのデータを使用しました。データの変更がデータベースに送信されていないため、他のトランザクションによって読み取られたデータは「Dirty Data」となり、この動作になりますは「Dirty Read」であり、「Dirty Data」に基づく操作では問題が発生する可能性があります。
-
変更の喪失: は、トランザクションがデータを読み取るときに、別のデータもそのデータにアクセスし、最初のトランザクションがデータを変更した後、2 番目のトランザクションもこのデータを変更したことを意味します。このように、最初のトランザクションでの変更結果が失われることを、変更ロスと呼びます。たとえば、トランザクション 1 はテーブル内のデータ
A=20
を読み取り、トランザクション 2 も A=20
を読み取り、トランザクション 1 は A=A-1
を変更します。トランザクション 2 も A=A-1
を変更し、最終結果は 19
になりますが、トランザクション 1 の変更レコードは失われます。
- 反復不可能な読み取り: は、トランザクション内で同じデータを複数回読み取ることを指します。トランザクションが終了する前に、別のトランザクションもデータにアクセスし、データを評価します。データが変更されると、最初のトランザクションで 2 回読み取られたデータは矛盾している可能性があります。この状況は non-repeatable read と呼ばれます。
-
ファントム読み取り (ファントム読み取り): ファントム読み取りは、非反復読み取りに似ています。ファントム読み取りは、複数行のデータを読み取るトランザクションを指します。トランザクションは終了していませんその後、別のトランザクションがデータを挿入します。後続のクエリでは、最初のトランザクションは、あたかも幻覚が起こったかのように、最初に読み取られたデータよりも多くのデータを読み取るため、ファントム読み取りと呼ばれます。
ノンリピートリーディングとファントムリーディングの違い:
ノンリピートリーディングの焦点は変更ですが、ファントムリーディングの焦点は追加ですまたは削除。
栗 1 (同じ条件、もう一度読むと読み取ったデータが異なります): トランザクション 1 の A さんは、自分の給与が 1000 であると読みました。操作はまだ終了しておらず、トランザクション 2 の B 氏は、A 氏の給与を 2000 に変更しました。A 氏が給与を再度読み取ると、2000 になりました。これは反復不可能な読み取りです。
栗 2 (同じ条件、1 回目と 2 回目で読み取られるレコードの数が異なります): 給与テーブルに給与が 3,000 を超える 4 人がいる場合、トランザクション 1 はすべての人を読み取ります。給与が 3,000 を超える場合、合計 4 つのレコードがクエリされました。これは、トランザクション 2 が給与が 3,000 を超える別のレコードをクエリしたためです。トランザクション 1 が再度読み取られ、5 つのレコードが見つかりました。これはファントム読み取りです。
4. トランザクション分離レベル
SQL 標準では 4 つの分離レベルが定義されています:
- * *READ-UNCOMMITTED: **最も低い分離レベル。コミットされていないデータ変更の読み取りを許可します。 は、ダーティ リード、反復不可能な読み取り、ファントム リードを引き起こす可能性があります。
- **READ-COMMITTED: **同時トランザクションによって送信されたデータの読み取りを許可します。 はダーティ リードを回避できますが、反復不可能なファントム リードが発生する可能性があります。
- **反復可能読み取り (REPEATABLE-READ): **トランザクション自体が変更されない限り、同じフィールドの複数の読み取りの結果は一貫しています。 はダーティ リードや未解決の読み取りを回避できます。読み出すとファントムリーディングが発生する可能性があります。
- **シリアル化可能 (SERIALIZABLE): **最高の分離レベル。ACID 分離レベルに完全に準拠し、すべてのトランザクションが順番に実行されます。 はダーティ リードと非反復読み取りを回避できます。 、幻の読書。
#分離レベル | ダーティ リード | 反復不可能な読み取り | ファントム リード |
未コミットの読み取り | √ | √ | √ |
# #送信された読み取り
|
#√ |
√ |
| ##繰り返し読み取り
| # × | √ |
| シリアル化可能
| #× | × |
|
MySQL InnoDB
ストレージ エンジンのデフォルトのトランザクション分離レベルは リピータブル リード (REPEATABLE-READ) で、コマンド select @@tx_isolation; で取得できます。
ステートメント View、MySQL 8.0
このステートメントは、SELECT @@transaction_isolation;
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
MySQL InnoDB
Repeatable read に変更されます。ストレージ エンジンのファントム読み取りのマージは避けられず、アプリケーションはロック読み取りを使用して、ロック読み取りに使用されるメカニズムが Next-Key Locks
であることを確認する必要があります。
分離レベルが低いほど、トランザクションによって要求されるロックが少なくなるため、ほとんどのデータベース システムの分離レベルは READ-COMMITTED 、InnoDB
ストレージ エンジンパフォーマンスを損なうことなく、デフォルトで REPEATABLE-READ を使用します。
InnoDB
ストレージ エンジンは通常、分散トランザクションの場合、serializable 分離レベルを使用します。
? 展開します (次の内容は、「MySQL Technology Insider: InnoDB Storage Engine (第 2 版)」の第 7.7 章からの抜粋です):
InnoDB ストレージ エンジンは XA をサポートします。トランザクション をサポートし、XA トランザクションを介した分散トランザクションの実装をサポートします。分散トランザクションとは、複数の独立したトランザクション リソースがグローバル トランザクションに参加できるようにすることを指します。トランザクション リソースは通常、リレーショナル データベース システムですが、他の種類のリソースである場合もあります。グローバル トランザクションでは、参加しているすべてのトランザクションをコミットまたはロールバックする必要があるため、トランザクションに対する元の ACID 要件がさらに向上します。さらに、分散トランザクションを使用する場合、InnoDB ストレージ エンジンのトランザクション分離レベルを SERIALIZABLE に設定する必要があります。
4. 実際の状況のデモ
MySQL
コマンドラインのデフォルト設定では、トランザクションは次のようになります。自動的に送信されます。つまり、SQL
ステートメントを実行すると、すぐに COMMIT
操作が実行されます。コマンド START TRANSACTION
を使用してトランザクションを開始できます。
次のコマンドを使用して、トランザクション分離レベルを設定できます。
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
実際の操作で使用する同時実行制御ステートメントのいくつかを見てみましょう:
-
START TRANSACTION | BEGIN
: トランザクションを明示的に開きます。
-
COMMIT
: トランザクションをコミットし、データベースへのすべての変更を永続的にします。
-
ROLLBACK
: ユーザーのトランザクションの最後までロールバックし、進行中のコミットされていない変更をすべて元に戻します。
(ダーティ リード) コミットされていない読み取り
(ダーティ リードを避ける) コミットされた読み取り
Non-repeatable read
これはまだです上の read-committed の図。コミットされていない読み取りは回避されますが、トランザクションが終了する前に、反復不可能な読み取りの問題が発生します。
繰り返し読み取り可能
[外部リンク画像の転送に失敗しました。ソースサイトにはリーチ対策が施されている可能性があります。このメカニズムでは、画像を保存して直接アップロードすることをお勧めします (img-ysjbfC4b-1651149978452)(https://qtspace.cn/contentimg/81.jpg)]
#phantom reading
ファントム リーディングの発生をデモンストレーションする
SQL スクリプト 1 給与 500 のレコードを初めてクエリするとき、レコードが 1 つだけあり、SQL スクリプト 2 が挿入します。給与 500 のレコードが取得されました。送信後、SQL スクリプト 1 が同じトランザクションで現在の読み取りクエリを再度使用したところ、給与 500 のレコードが 2 つ出現したことがわかりました。これは次のとおりです。幻の読み物。 ファントム リーディングと非反復リーディングにはいくつかの類似点がありますが、非反復リーディングの焦点は変更にあるのに対し、ファントム リーディングの焦点は追加または削除です。 ファントム読み取りを解決する方法
トランザクション分離レベルを - SERIALIZABLE
に調整します。
反復読み取りトランザクション レベルで、トランザクション操作のテーブルにテーブル ロックを追加します。 - 反復可能な読み取りトランザクション レベルで、トランザクション操作のテーブルに
- Next-Key Locks
を追加します。
説明: Next-Key Locks 行ロック ギャップ ロックと同等
[関連する推奨事項: mysql ビデオ チュートリアル]
以上がmysql トランザクション分離レベルとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。