InnoDB がトランザクション分離レベルを巧みに実装する方法

InnoDB がトランザクション分離レベルを巧みに実装する方法

序文

前回の記事「MySQL ロック メカニズムの詳細説明」では、InnoDB のロック メカニズムについて詳しく説明しました。ロック メカニズムは、同時実行状況でデータの正確性を確保するために使用されます。データの正確性を確保するには、通常、トランザクションが必要です。MySQL ストレージ エンジン InnoDB は、ロック メカニズムを通じて、トランザクションの分離特性に 4 つの分離レベルを巧みに実装しています。

トランザクションの ACID 特性。I は分離を表します。分離とは、複数のユーザーの同時トランザクションが同じデータベースにアクセスする場合、あるユーザーのトランザクションが他のユーザーのトランザクションによって干渉されず、複数の同時トランザクションが互いに分離されることを意味します。

トランザクションの特性は誰もが知っています。データベースの一貫性と分離性は、トランザクションを実装するための基本的な考え方です。システムに多数の同時アクセスがある場合、データベース独自のトランザクション分離レベルを理解して巧みに適用することが、強力な同時処理機能を備えた堅牢なコードを作成する上で重要な役割を果たします。

1. 取引が互いに干渉し合う仕組み

1 つのトランザクションが他のトランザクションにどのように干渉しますか?たとえば、次の表があります。

テーブル lock_example(id smallint(10),name varchar(20),主キー id) を作成します。engine=innodb;

表には次のデータが含まれています。

1、張山
2、リシ
3、王武

デモ1:

トランザクション A が最初に実行され、コミットされていない状態になります。

t 値に挿入します(4, 'zhaoliu');

後で実行されるトランザクション B もコミットされません。

t から * を選択します。

トランザクション B がレコード (4、zhaoliu) を読み取ることができる場合、トランザクション A がトランザクション B に影響を与えていることを意味します。この影響は「ダーティ リード」と呼ばれ、コミットされていないトランザクション操作のレコードが読み取られます。

デモ2:

トランザクション A を最初に実行します。

id=1 の t から * を選択します。

結果セットは

1,張さん

トランザクション B は後で実行され、コミットされます。

更新 t set name=xxx where id=1;

専念;

トランザクション A は同じクエリを再度実行します。

id=1 の t から * を選択します。

結果セットは次のとおりです。

1、xxx

今回は、コミットされたトランザクション B がトランザクション A に影響を与えます。この影響は「非反復読み取り」と呼ばれ、トランザクション内の同じクエリが異なる結果を生成します。

デモ3:

トランザクション A を最初に実行します。

id>3 の t から * を選択します。

結果セットは次のとおりです。

NULL

トランザクション B は後で実行され、コミットされます。

t値(4, zhaoliu)に挿入します。

専念;

トランザクション A は最初に id>3 を照会し、結果は NULL なので、id 4 のレコードを挿入します。

t値(4, xxoo)に挿入します。

結果セットは次のとおりです。

エラー: キーが重複しています。

こう思っているかもしれません。 。 。冗談でしょ?確認したところ、id>3 の場合は空のセットでしたが、id=4 を挿入すると PK の競合が発生したと表示されました。 →_→

今回、コミットされたトランザクション B がトランザクション A に与える影響は「ファントム リード」と呼ばれます。

前述のように、同時トランザクションにより、他のトランザクションでダーティ リード、反復不可能なリード、ファントム リードが発生する可能性があります。上記の状況を回避するために、InnoDB はどのような取り組みを行ってきたのでしょうか?

2. InnoDB はどのようなトランザクション分離レベルを実装していますか?

InnoDB は 4 つの異なるトランザクション分離レベルを実装します。

  • コミットされていない読み取り
  • 読み取りコミット (RC)
  • 繰り返し読み取り (RR)
  • シリアル化可能

異なるトランザクションの分離レベルは、実際には一貫性と同時実行性の間のトレードオフです。

3. InnoDB で 4 つのトランザクション分離レベルを実装するにはどうすればよいですか?

InnoDB は、さまざまな分離レベルを実装するためにさまざまなロック戦略を使用します。

a. コミットされていない読み取り

このトランザクション分離レベルでは、選択ステートメントはロックされず、スナップショット読み取りも行われません。

SELECT ステートメントはロックなしで実行されます。

このとき、矛盾したデータが読み取られる可能性があり、これを「ダーティ リード」と呼びます。これは、同時実行性が最も高く、一貫性が最も低い分離レベルです。

b. 読み取りコミット (RC)

  • 通常の選択はスナップショット読み取りです。
  • ロックされた選択、更新、削除ステートメントは、外部キー制約チェックと重複キーチェックが進行中の場合を除いて、レコード ロックのみを使用します。
  • このレベルではギャップロックと次のキーロックは無効です。

この時点では、他のトランザクションの挿入は引き続き実行される可能性があり、ファントム レコードが読み取られる可能性があります。このレベルは最も一般的に使用されます。また、ロック解除された選択の場合、繰り返し不可能な読み取りが発生する可能性があります。

このレベルでは、スナップショット読み取りによってダーティ リードが防止されます。このレベルでのスナップショット読み取りでは、常に最新の行データ スナップショットを読み取ることができるため、当然、コミットされたトランザクションによって書き込まれる必要があり、そのため、繰り返し不可能な読み取りが発生する可能性があります。

c. 繰り返し読み取り (RR)

これは、RR における InnoDB のデフォルトの分離レベルです。

  • 通常の選択では、一貫性のある非ロック読み取りであるスナップショット読み取りが使用され、最下層で MVCC を使用して実装されます。
  • ロックされた選択 (共有モードでの ... の選択 / 更新用の ... の選択)、更新、削除ステートメントなどでは、一意のインデックスに対して一意の検索条件 (この場合はレコード ロックを使用) を使用するか、範囲型の検索条件 (この場合はギャップ ロックまたは隣接キー ロックを使用) を使用するかによってロックが異なります。
  • 一意のインデックスで一意のクエリ条件を使用すると、レコード間の間隔をブロックする代わりにレコード ロックが使用されます。つまり、ギャップ ロックと次のキー ロックは使用されません。
  • 範囲クエリ条件または非一意インデックスの場合、ギャップ ロックと隣接キー ロックを使用してインデックス レコード間の範囲をロックし、範囲間のレコードの挿入を防止します。これにより、ファントム行レコードと反復不可能な読み取りの生成を回避できます。

このレベルでは

  • スナップショット読み取りとロック間隔を使用して、ファントム読み取りと反復不可能な読み取りを回避します。
  • トランザクションが最初にレコードを読み取る時間は T です。将来的には、T 以降にコミットされたトランザクションによって書き込まれたレコードは読み取られなくなります。これにより、連続した読み取りで同じ結果セットが読み取られるようになり、繰り返し不可能な読み取りを防止できます。
  • RR では、ギャップ ロックと隣接キー ロックによってファントム リード問題が解決されます。

d. シリアル化可能

このトランザクション分離レベルでは、すべての select ステートメントが暗黙的に共有モードの select ... に変換されます。つまり、共有読み取りロック (S ロック) がデフォルトで設定されます。

したがって、トランザクション A が最初に次の SQL ステートメントを実行すると、クエリされた行の IS ロック (他の IS および IX ロックと互換性がある) を取得しようとします。このとき、他のトランザクションもこれらの行の IS ロックまたは S ロックを取得できます。ただし、トランザクション A が次に行の一部を更新または削除すると、X ロックを取得します。他のトランザクションは、IS ロックを取得しようとするため、通常の SELECT ステートメントを実行してもブロックされます。ただし、IS ロックと X ロックは相互に排他的です。これにより、ダーティ リード、非反復リード、ファントム リードが回避され、すべてのトランザクションはシリアルにのみ実行できます。

...を選択します。

これは最も一貫性がありますが、同時実行性は最も低い分離レベルです。同時実行性の高いシナリオでは、上記の 2 つの分離レベル a と d はほとんど使用されません。

4. 結論

同時実行トランザクション間の相互干渉により、ダーティ リード、反復不可能なリード、ファントム リードなどの問題が発生する可能性があります。

InnoDB は、SQL92 標準の 4 つの分離レベルを実装します。

  • コミットされていない読み取り: 選択がロックされていないため、ダーティ リードが発生する可能性があります。
  • 読み取りコミット (RC): 通常の選択スナップショット読み取り、ロック選択/更新/削除ではレコード ロックが使用され、繰り返し不可能な読み取りが発生する可能性があります。
  • 繰り返し読み取り (RR): 通常の選択スナップショット読み取り、ロック選択/更新/削除。クエリ条件に応じて、レコード ロック、ギャップ ロック/即時キー ロックが選択され、ファントム レコードが読み取られるのを防ぎます。
  • シリアル化: 共有モードでは、select は暗黙的に select ... に変換されます。これは、update および delete とは相互に排他的になります。

InnoDBのデフォルトの分離レベルはRRであり、最も一般的に使用される分離レベルはRCである。

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。

以下もご興味があるかもしれません:
  • Innodb トランザクション分離レベルと MySQL のロックの関係に関するチュートリアル
  • MySQL データベースのトランザクション分離レベル (トランザクション分離レベル) の概要
  • MySQL の 4 つのトランザクション分離レベルの詳細な説明と比較
  • MySQL トランザクション分離とパフォーマンスへの影響の詳細な分析
  • MySQL の 4 つのトランザクション分離レベルの詳細な説明
  • MySQLデータベースのトランザクション分離レベルの詳細な説明
  • MySQL の 4 つのトランザクション分離レベルを例を使って分析する

<<:  JSはjQueryのappend関数を実装します

>>:  Docker でタイムゾーンの問題に対処する方法

推薦する

MySQLのダウンロードとインストールのプロセスの詳細な説明

1: MySqlをダウンロードする公式サイトのダウンロードアドレス: https://dev.mys...

Jsモジュールパッケージのエクスポートの使用法と違いにはインポートが必要

目次1. Commonjsのエクスポートとrequireの使用1.1 CommonJS エクスポート...

フォント宝庫 50 種類の素晴らしい無料英語フォントリソース パート 2

デザイナーは独自のフォント ライブラリを持っているため、プロジェクトの設計時にすぐに使用できます。今...

Vueシングルページアプリケーションの事前レンダリング方法の例

目次序文vue-cli 2.0 バージョンvue-cli 3.0 バージョン要約する序文vue-cl...

Docker に ElasticSearch 6.x をインストールする詳細なチュートリアル

まず、イメージをプルします(またはコンテナを作成するだけで、自然にプルされます)。 docker p...

HTML 選択ボックスのプレースホルダーの作成に関する問題

テキスト入力でプレースホルダーを使用していますが、問題なく動作します。しかし、選択ボックスにはプレー...

ウェブページで Enter キーを押すと自動的にフォームを送信し、他のページにジャンプするソリューション

ウェブページでEnterキーを押すと、フォームは自動的に送信され、他のページに移動します。クエリフォ...

MySQL インデックスの詳細な説明

目次1. インデックスの基本1.1 はじめに1.2 インデックスの仕組み1.3 インデックスの種類1...

Vueの最初のレンダリングのプロセス全体についての簡単な説明

目次1. Vueの初期化vue エントリ ファイルフルバージョンとランタイムバージョンの違い1.1、...

HTML 5 プレビュー

<br />オリジナル: http://www.alistapart.com/artic...

カンマで区切られたmysqlの分割関数の実装

1: 文字列を区切るためのストアドプロシージャを定義する 区切り文字 $$ `mess`$$ を使う...

js はマウスによる画像の切り替えを実装します (タイマーなし)

この記事の例では、マウス切り替え画像を実現するためのjsの具体的なコードを参考までに共有しています。...

JavaScript はモーダルボックスのドラッグ効果を実現します

これはモーダル ボックスのドラッグのケースです。ここで実装する関数は次のとおりです。 1. ポップア...

Win7 で IIS7 Web および FTP サービスを完全にアンインストールする方法

昨日、パソコンにPHP開発環境をセットアップした後、Apacheサーバーを再起動するとエラーが続きま...

JavaScriptはシンプルな計算機能を実装します

この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...