Msyql トランザクション分離について知っておくべきこと

Msyql トランザクション分離について知っておくべきこと

トランザクションとは何ですか?

トランザクションは、データベース管理システムの実行プロセスにおける論理単位であり、有限の一連のデータベース操作で構成されます。データベース トランザクションは通常、データベースに対する一連の読み取り/書き込み操作で構成されます。目的は次の 2 つです。

  1. データベース操作シーケンスが障害から正常状態に回復する方法を提供し、また、異常な状態であってもデータベースが一貫性を維持する方法も提供します。
  2. 複数のアプリケーションが同時にデータベースにアクセスする場合、アプリケーション間で分離方法を提供して、アプリケーション間の操作が相互に干渉するのを防ぐことができます。

分離と分離レベル

トランザクションといえば、ACID (原子性、一貫性、独立性、永続性) を思い浮かべるでしょう。今日は、I、つまり「独立性」についてお話します。データベース上で複数のトランザクションが同時に実行されると、ダーティ リード、非反復リード、ファントム リードが発生する可能性があります。これらの問題を解決するために、「分離レベル」という概念が導入されました。分離レベルが強くなるほどパフォーマンスは低下するため、パフォーマンスと分離レベルの間でバランスを取る必要があります。 SQL 標準トランザクション分離レベルには次のものがあります。

  • コミットされていない読み取り: トランザクションがコミットされると、そのトランザクションによる変更は他のトランザクションで確認できるようになります。ダーティリードが発生します。
  • コミットされた読み取り: トランザクションがコミットされると、そのトランザクションによる変更が他のトランザクションで確認できるようになります。これにより、繰り返し不可能な読み取りが発生します。
  • 繰り返し可能な読み取り: トランザクションの実行中に表示されるデータは、トランザクションの開始時に表示されたデータと常に一致しています。もちろん、繰り返し読み取り分離レベルでは、コミットされていない変更も他のトランザクションからは見えません。ファントムリードが発生します。
  • シリアル化可能: 名前が示すように、同じレコード行に対して、「書き込み」は「書き込みロック」を追加し、「読み取り」は「読み取りロック」を追加します。読み取り/書き込みロックの競合が発生した場合、後からアクセスされるトランザクションは、前のトランザクションが完了するまで待機してから実行を続行する必要があります。

分離レベルダーティリード繰り返し不可能な読み取りファントムリード
コミットされていない読み取り出現する可能性がある出現する可能性がある出現する可能性がある
コミットされた読み取り許可されていません出現する可能性がある出現する可能性がある
繰り返し読み取り許可されていません許可されていません出現する可能性がある
シリアル化許可されていません許可されていません許可されていません

主な理由は、コミットされた読み取りと繰り返し可能な読み取りを区別することが難しいため、小さな例を見てみましょう。まずテーブルを作成し、データ1を挿入します

データベーステストを作成します。
使用テスト;
テーブル test(id int primary key) を作成します。
test(id) 値(1) に挿入します。

取引A取引B
トランザクションクエリを開始して1を取得取引を開始する
クエリの結果は1
1を2に変更
V1を取得するためのクエリ
トランザクションBをコミットする
V2を取得するためのクエリ
トランザクションAをコミットする
V3を取得するためのクエリ

異なる分離レベルでのトランザクション A の異なる戻り結果、つまり図の V1、V2、V3 の戻り値を見てみましょう。

  • 分離レベルが「コミットされていない読み取り」の場合、V1 の値は 2 になります。この時点ではトランザクション B はまだコミットされていませんが、その結果は A によって確認されています。したがって、V2 と V3 も 2 です。
  • 分離レベルが「読み取りコミット」の場合、V1 は 1、V2 は 2 になります。トランザクション B の更新は、コミットされた後にのみ A で表示されます。したがって、V3 の値も 2 になります。
  • 分離レベルが「繰り返し読み取り」の場合、V1 と V2 は 1、V3 は 2 になります。 V2 が依然として 1 である理由は、実行中にトランザクションによって参照されるデータは、実行前と実行後に一貫している必要があるという要件に従っているためです。
  • 分離レベルが「シリアル化可能」の場合、トランザクション B は「1 から 2 への変更」を実行するときにロックされます。トランザクション B は、トランザクション A がコミットされた後にのみ実行を続行できます。したがって、Aの観点から見ると、V1とV2の値は1、V3の値は2です。

データベースにビューが作成され、アクセス時にビューの論理結果が使用されます。 「繰り返し可能読み取り」分離レベルでは、このビューはトランザクションの開始時に作成され、トランザクション全体で使用されます。 「Read Committed」分離レベルでは、このビューは各 SQL ステートメントの実行の開始時に作成されます。 ここで注目すべきは、「コミットされていない読み取り」分離レベルでは、ビューの概念を使用せずにレコードの最新の値を直接返すのに対し、「シリアル化可能」分離レベルでは、並列アクセスを回避するためにロックを直接使用するということです。

では、**「繰り返し読み取り」** のシナリオはいつ必要になるのでしょうか?

個人の銀行口座の表を管理しているとします。 1 つのテーブルには毎月末の残高が保存され、もう 1 つのテーブルには請求書の詳細が保存されます。このとき、データの校正、つまり先月の残高と現在の残高の差が今月の請求明細と一致しているかどうかを判断する必要があります。校正プロセス中に、ユーザーが新しいトランザクションを実行しても、校正結果に影響が及ばないことを期待する必要があります。

トランザクション分離の実装

実際、MySQL では、レコードが更新されるたびに、レコードごとにロールバック操作が記録されます。レコードの最新の値を使用して、ロールバック操作を通じて以前の状態の値を取得できます。値が 1 から 2、3、4 に順番に変更されると、ロールバック ログには次のようなレコードが記録されます。

現在の値は 4 ですが、このレコードを照会すると、異なる時間に開始されたトランザクションには異なる読み取りビューが設定されます。図に示すように、ビュー A、B、C では、このレコードの値はそれぞれ 1、2、4 です。同じレコードがシステム内で複数のバージョンを持つことができ、これがデータベースのマルチバージョン同時実行制御 (MVCC) です。読み取りビュー A の場合、1 を取得するには、図内のすべてのロールバック操作を順番に実行して現在の値を取得する必要があります。 4 を 5 に変更する別のトランザクションがある場合でも、このトランザクションは読み取りビュー A、B、および C に対応するトランザクションと競合しません。

ロールバック ログは永久に保存することはできません。いつ削除すればよいですか?

不要になったら削除してください。つまり、システムは、これらのロールバック ログを使用する必要がないトランザクションがある場合、ロールバック ログを削除すると判断することになります。

いつ必要でなくなるのでしょうか?

それは、このロールバック ログより前の読み取りビューがシステム内に存在しない場合です。

トランザクションの使用を避けるべきなのはなぜですか?

トランザクションとは、システム内に非常に古いトランザクション ビューが存在することを意味します。トランザクションがコミットされる前に、ロールバック レコードを保持する必要があり、大量のストレージ領域が占有されることになります。さらに、トランザクションはロック リソースを占有し、データベースがダウンする可能性があります。

上記は、msyql トランザクション分離について知っておく必要のある詳細です。mysql トランザクション分離の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

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

<<:  JavaScript 変数の昇格についての簡単な説明

>>:  Ubuntu 20.04 ファイアウォール設定の簡単なチュートリアル (初心者)

推薦する

Linux suse11でルートパスワードを忘れた場合に変更する方法の簡単な分析

SUSE Linuxでルートパスワードを忘れた場合の解決方法SUSE (Linux オペレーティング...

mysql8.0 Windows x64 zip パッケージのインストールと構成のチュートリアル

MySQL 8 Windows版 zipインストール手順(ダウンロードアドレス) 1. ZIPファイ...

JavaScript ECharts の使用方法の説明

以前、プロジェクトを行う際に ECharts を使用しました。今日はそれをメモとして整理し、より多く...

MySQL カーディナリティ統計の簡単な分析

1. カーディナリティとは何ですか?カーディナリティとは、MySQL テーブルの列内の異なる値の数を...

適応型ウェブページを設計および作成する方法

3G の普及により、携帯電話を使ってインターネットにアクセスする人が増えています。モバイル デバイス...

Azure Container Registry を使用してイメージを保存する際の問題

Azure Container Registry は、Docker Registry 2.0 仕様に...

Reactでカスタムフックを作成する方法を教えます

1. カスタムフックとは何かロジックの再利用簡単に言えば、カスタム フックを使用すると、特定のコンポ...

MySQLフィルタリングレプリケーションのアイデアの詳細な説明

目次mysql フィルター レプリケーションメインデータベースに実装ライブラリから実装いくつかの質問...

Tencent Cloud Serverをゼロから導入する方法

初めての投稿ですので、間違いや問題点などありましたら、コメント欄で指摘していただければ、今後改善させ...

シンプルなショッピングカート機能を実現するjs

この記事の例では、簡単なショッピングカート機能を実現するためのjsの具体的なコードを参考までに共有し...

Tableとdivの簡単な紹介と使い方

ウェブフロントエンド1学生証名前性別年01張三男20 02李思女性21総人数60フォームのコンポーネ...

Vueアイコンセレクターのサンプルコード

出典: http://www.ruoyi.vip/ 'vue' から Vue をイン...

Vueは、サイドナビゲーションバーをタブページに関連付けるサンプルコードを実装します。

目次テクノロジースタック効果分析するテクノロジースタックサイドバー用Antdtabは要素を使用します...

http-proxy-middlewareを使用してNodeでプロキシクロスドメインを実装する方法と手順

目次1. プロキシモジュールをインストールする2. プロキシを設定する1. プロキシモジュールをイン...