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 を使用してシンプルな矢印アイコンを実装するコード
>>: レンダリング関数を使用して、拡張性の高いコンポーネントをカプセル化する
導入MySQL データベースの読み取りと書き込みの分離を設定すると、データベースに対する書き込み操作...
目次序文1. 親コンポーネントが子コンポーネントに値を渡す2. サブコンポーネントのprops型制約...
1. モジュールをインポートし、検証状態を定義する PIL から Image、ImageDraw、...
前回の記事では、次のことを紹介しました。 MySQL8.0.20 インストール チュートリアルとイン...
目次レンダリングAPIの変更レンダリング関数のパラメータレンダリング関数のシグネチャの変更VNode...
今日、最終プロジェクトに取り組み始めましたが、今年はMySQLデータベースを使用したため、Navic...
目次1. 問題の説明2. 問題分析3. 問題解決1. Dockerのディスク使用量を確認する2. 再...
mysql が閉じない場合の解決策:コンピュータのタスクバーを右クリックしてタスクマネージャーを開き...
URL 書き換えは、Web サイトの優先ドメインを決定するのに役立ちます。同じリソース ページの複数...
目次序文グラフィックドライバーをインストールするCUDAをアンインストールするCUDAをインストール...
Canvas は HTML5 の新しいタグです。js を使用して Canvas 描画 API を操作...
目次必要:アイデア:レッスン:テキストを共有する:要約する必要:インターフェイスからサブメニュー デ...
テキストのレイアウトには、言語に応じていくつかの書式設定要件があります。たとえば、簡体字中国語では、...
1. MySQL 5.6をインストールした後、正常に有効化できないMySQL の圧縮バージョンは、解...
1. サーバーにDockerをインストールする yumでdockerをインストール設定ファイルを変更...