1 トランザクションの同時実行で発生する問題1.1 ダーティリードトランザクションが、別のトランザクションによって変更されたがコミットされていないデータを読み取る場合、それはダーティ リードと呼ばれます。 1.2 繰り返し不可能な読み取りトランザクション内で同じレコードが 2 回取得され、2 回取得された結果が異なる場合、この現象は非反復読み取りと呼ばれます。 1.3 ファントムリードトランザクションが同じクエリ条件で 2 回 (または複数回) クエリを実行し、見つかったエントリの数に矛盾がある場合、ファントム リードと呼ばれます。 2つの分離レベル同時トランザクションの実行中に発生する可能性のあるいくつかの問題を紹介しました。これらの問題にはそれぞれ異なる優先順位があります。これらの問題を重大度に応じてランク付けします。 ダーティリード > 反復不可能なリード > ファントムリード SQL 標準では、異なる分離レベルに対して、同時トランザクションの重大度が異なる可能性があることが規定されています。 具体的な状況は以下のとおりです。
SQL 標準では、異なる分離レベルでは、同時トランザクションで次のようにさまざまな重大度の問題が発生する可能性があることが規定されています。
3 バージョンチェーンInnoDB ストレージ エンジンを使用するテーブルの場合、クラスター化インデックス レコードには 2 つの必要な非表示列が含まれていることがわかっています (row_id は不要であり、作成するテーブルに主キーまたは NULL 以外の UNIQUE キーがある場合は row_id 列は含まれません)。 挿入されたレコードのトランザクション ID が 80 であると仮定すると、この時点でのレコードの概略図は次のようになります。 トランザクション ID 100 と 200 を持つ 2 つのトランザクションがこのレコードに対して UPDATE 操作を実行するとします。操作フローは次のようになります。 TRX100: UPDATE t_people SET name = 'Guan Yu' WHERE number = 1; UPDATE t_people SET name = '张飞' WHERE number = 1; TRX200: UPDATE t_people SET name = 'Zhao Yun' WHERE number = 1; UPDATE t_people SET name = 'Zhuge Liang' WHERE number = 1; レコードが変更されるたびに、undo ログが記録されます。各 undo ログには roll_pointer 属性もあります (レコードに以前のバージョンがないため、INSERT 操作に対応する undo ログにはこの属性がありません)。これらの undo ログは接続してリンク リストを形成できるため、現在の状況は次の図のようになります。 レコードが更新されるたびに、古い値が、たとえレコードの古いバージョンであっても、元に戻すログに入れられます。更新回数が増えると、すべてのバージョンが roll_pointer 属性によってリンク リストに接続されます。このリンク リストをバージョン チェーンと呼び、バージョン チェーンの先頭ノードは現在のレコードの最新の値です。さらに、各バージョンには、バージョンの世代に対応するトランザクション ID も含まれます。このレコードのバージョン チェーンは、同じレコードにアクセスする同時トランザクションの動作を制御するために使用できます。このメカニズムは、 4 読み取りビュー4.1 ReadView の定義InnoDB は、主に次の 4 つの重要な内容を含む ReadView の概念を提案しています。
4.2 アクセス制御この ReadView を使用すると、レコードにアクセスするときに、レコードのバージョンが表示されているかどうかを判断するには、次の手順に従うだけで済みます。
4.3 隔離の再考READ UNCOMMITTED 分離レベルを使用するトランザクションの場合、コミットされていないトランザクションによって変更されたレコードを読み取ることができるため、レコードの最新バージョンを直接読み取ることができます。 SERIALIZABLE 分離レベルを使用するトランザクションの場合、InnoDB はロックを使用してレコードにアクセスします。 MySQL では、READ COMMITTED 分離レベルと REPEATABLE READ 分離レベルの大きな違いは、ReadView が生成されるタイミングです。 4.3.1 コミットされた読み取り読み取りが送信されると、各データの読み取りの前に ReadView が生成されます。 ここで、READ COMMITTED 分離レベルを使用するトランザクションの実行が開始されるとします。 詳細なクエリ: # READ COMMITTED 分離レベルを使用するトランザクション # トランザクション 100 と 200 はコミットされておらず、列名の値は Liu BeiSELECT name FROM t_people WHERE number = 1; です この SELECTET の実行プロセスは次のとおりです。
繰り返し不可能な読み取り: トランザクション 100 および 200 が開始されると、読み取られる名前は Liu Bei になります。トランザクション100がコミットされると、トランザクション分離レベルが読み取りコミットであるため、読み取りごとにReadViewが作成されます。トランザクション200が読み取られると、生成されたReadView m_idsは[200]になります。このとき、読み取りルールに従って読み取られた名前はZhang Feiです。 # READ COMMITTED 分離レベルでトランザクション BEGIN を使用します。 # SELECE1: トランザクション 100 と 200 は送信されず、名前の値は Liu Bei です。SELECT name FROM t_people WHERE number = 1; # SELECE2: トランザクション 100 はコミットされ、トランザクション 200 はコミットされません。# トランザクション 200 のトランザクション クエリでは、名前の値は Zhang Fei であり、反復不可能な読み取りが発生します。 SELECT name FROM teacher WHERE number = 1; 4.3.2 繰り返し読み取り再読み取り可能。初めてデータを読み取るときに ReadView を生成します。 繰り返し不可能な読み取りの問題を解決します。100 トランザクションと 200 トランザクションが有効になり、ReadView が作成されます。m_ids は [100,200] で、読み取られた名前は Liu Bei です。トランザクション100がコミットされると、再読み取りトランザクション分離レベルにより、ReadViewは1つだけ作成され、m_idsは[100,200]のままです。このとき、読み取りルールに従って読み取られた名前はLiu Beiのままです。 5 ファントムリードトランザクションが同じクエリ条件で 2 回 (または複数回) クエリを実行し、見つかったエントリの数に矛盾がある場合、ファントム リードと呼ばれます。 REPEATABLE READ 分離レベルのトランザクション T1 は、まず検索条件に基づいて複数のレコードを読み取り、次にトランザクション T2 は対応する検索条件を満たすレコードを挿入してコミットし、最後にトランザクション T1 は同じ検索条件に基づいてクエリを実行します。結果はどうなるでしょうか? ReadView の比較ルールによれば、トランザクション T2 がトランザクション T1 より前に開始されたかどうかに関係なく、トランザクション T1 は T2 のコミットを確認できません。ただし、REPEATABLE READ 分離レベルの InnoDB の MVCC では、ファントム リードを完全に禁止するのではなく、ファントム リードを大幅に回避できます。 #SELECT: スナップショットを読み取りました。更新: 現在既読。 REPEATABLE READ は、スナップショット読み取りのファントム読み取り問題を解決できます。現在のファントムリード問題は解決できません。 例: 1 beginを実行し、select *を実行します。 2 別のウィンドウを開いて、挿入、選択、コミットを実行します。 3 元のウィンドウに戻ってクエリを実行します 4 更新を実行して送信する 5 検索 6 結論上記の説明から、いわゆる MVCC (Multi-Version Concurrency Control) は、READ COMMITTD と REPEATABLE READ の 2 つの分離レベルでトランザクションを使用して通常の SELECT 操作を実行するときに、レコードのバージョン チェーンにアクセスするプロセスを指すことがわかります。これにより、異なるトランザクションの読み取り書き込み操作と書き込み読み取り操作を同時に実行できるため、システム パフォーマンスが向上します。 READ COMMITTD と REPEATABLE READ という 2 つの分離レベルの大きな違いは、ReadView が生成されるタイミングです。READ COMMITTD は、通常の SELECT 操作の前に ReadView を生成しますが、REPEATABLE READ は、最初の通常の SELECT 操作の前にのみ ReadView を生成し、後続のクエリ操作ではこの ReadView を再利用するため、基本的にファントム リードを回避できます。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: HTML で div+CSS を使用してシンプルな矢印アイコンを実装するコード
>>: レンダリング関数を使用して、拡張性の高いコンポーネントをカプセル化する
クエリを最適化するExplain ステートメントを使用してクエリ ステートメントを分析するExpla...
背景何が起こったかというと、Luzhu は偶然、宇宙で最高の外部スピーカーを備えた携帯電話について知...
MySQLサーバーは--skip-grant-tablesオプションで実行されているため、このステー...
クラスターの展開の概要172.22.12.20 172.22.12.21 172.22.12.22 ...
[LeetCode] 176. 2番目に高い給与従業員テーブルから 2 番目に高い給与を取得する ...
目次問題のシナリオ:解決: 1. フィールドを個別にチェックする2. フォームフィールドの下のフィー...
Java を使用してシステム時間を取得し、それを MySQL データベースに保存した後、時間タイプが...
Samba サービス:このコンテンツはサンバサービス学習者の参考用ですケースの説明:企業の管理者は、...
目次背景仮想ファイルのインポート例書類タイプスクリプトのサポート要約する背景新しいプロジェクトで v...
目次道具:ログインシナリオ:練習する:シナリオ1: 思考と実践シナリオ2: 思考と実践要約する道具:...
コンピュータシステム: win7この記事は主に写真に基づいており、多くの写真が含まれていますCent...
チェーンプログラミングの実装原理jQuery を使用すると、開発者は常にドット構文を使用して独自のメ...
ページ ヘッダーの固定レイアウトは、以前は position:fixed を使用して実装されていまし...
Linux のデフォルトの ssh リモート ポートは 22 です。デフォルトのポートは、悪意のある...
静的ウェブサイトをホストできるサーバーは数多くあります。この記事では、nginx、apache、to...