MySQLトランザクションの特徴と分離レベルについてお話ししましょう

MySQLトランザクションの特徴と分離レベルについてお話ししましょう

インターネットにはすでにこの種の記事が溢れていますが、私がこれをまだ書いている理由は単純です。それは、私自身の理解を書き留めておくためです。

序文

この記事は MySQL についての私の個人的な理解であり、使用されているエンジンは InnoDb です。まず、トランザクションの概念について説明します。『High Performance MySQL』第 3 版では、トランザクションについて次のように説明されています。

トランザクションは、一連のアトミック SQL クエリ、または独立した作業単位です。データベース エンジンがクエリ セットのすべてのステートメントをデータベースに正常に適用できる場合、クエリ セットが実行されます。クラッシュやその他の理由によりいずれかのステートメントを実行できない場合は、いずれのステートメントも実行されません。

つまり、トランザクションは一体化した単位であり、その中の SQL ステートメントは、複数のコンポーネントで構成されている一部の製品のように、個別に実行されることはありません。ただし、コンポーネントを個別に販売することは絶対にありません。購入したい場合は、製品全体を購入してください。そうでなければ、販売しません。

トランザクションについて簡単に理解した後、トランザクションの目的はデータの正確性と一貫性を確保することであることも知っておく必要があります。この目的のために、その 4 つの特性が生まれます (詳細は後述)。これらの 4 つの特性を実現するために、分離のための 4 つの分離レベルを含む多くの具体的な実装が必要です。これらの 4 つの分離レベルにより、3 つの問題 (ダーティ リード、非反復リード、ファントム リード) が発生しています。これが一般的な関係です。次に、これらが何であるかを見てみましょう。

1 4つの特性(ACID)

トランザクション特性といえば、間違いなくACIDが真っ先に思い浮かびます。しかし、ACIDという4文字に加えて、別のことについても話す必要があります。

原子性: トランザクションは分割できない最小単位として扱われることを意味します。トランザクション全体の操作は、原子と同じように、すべて正常に実行されるか、まったく実行されないかのどちらかです。(クォークについては触れないでください。) ここでの実行は、正常に実行されることを指します。1 つの操作が失敗すると、その操作はどれも実行されません。これは、よく見られるロールバックでもあります。

一貫性: 本書で説明されている意味は、トランザクションが常に 1 つの一貫した状態から別の一貫した状態に移行するということです。私の理解では、関係するデータ範囲内で保存され、つまり、全体のデータは変更されません。送金の一般的な例を考えてみましょう。口座 A は口座 B に 200 元を送金します。すると、A と B で構成されるデータ範囲は変更されません (-200+200=0) が、データの構成は変更されたため、1 つの一貫した状態から別の一貫した状態になります。

​​ 分離: 一般的に、1 つのトランザクションの操作は他のトランザクションからは見えません。つまり、トランザクションは通常は独立しています。しかし、これはデータベースの分離レベルに関係しています。特定の分離レベル (そうです、コミットされていないクラスメートであるあなたです) を除いて、他の分離レベルは見えず、このトランザクション可視性レベルはほとんど使用されないため、「一般的に言えば」と言われています。

永続性: トランザクションが完了すると、トランザクションによって行われたデータの変更は永続的に有効になり、変更されなくなります (別のトランザクションによって変更されない限り)。しかし、この本では、これは実際には実装戦略に関連していると述べていますが、これは少し無理が​​あるように思えます(ええ、わかりません!)。

以上がトランザクションの 4 つの特徴です。分離の実装はデータベースの分離レベルによって異なります。

2 データベース分離レベル

MySQL には 4 つの分離レベルがあります。各分離レベルは異なるトランザクションに対応し、異なる問題を引き起こす可能性があります。

​​ コミットされていない読み取り: この分離レベルでは、1 つのトランザクションで実行された操作は、コミットされていない場合でも他のトランザクションで参照できます。このレベルでは、トランザクションは他のトランザクションによってコミットされていないダーティ データを読み取る可能性があります。つまり、ダーティ リードが発生する可能性があります。下の図に示すように、シーケンス番号は実行順序を示します。

ご覧のとおり、ページ 1 のトランザクションでデータがテスト テーブルに挿入されています。まだ送信されていない場合でも、送信されたデータはページ 2 の別のトランザクションで確認できます。

コミットされた読み取り: トランザクションがコミットされると、他のトランザクションはトランザクションに加えられた変更を確認できるようになります。この分離レベルでは、同じトランザクションで同じクエリが実行されても、異なるデータが読み取られる可能性があり、これは非反復読み取りと呼ばれます。非反復読み取りは、コミットされていない読み取りでも発生する可能性があります。例は以下のとおりです

繰り返し読み取り: これは MySQL のデフォルトの分離レベルです。トランザクションの開始時に、その時点でのスナップショットが保存されます (ここではより具体的に説明します。実際には、トランザクションの開始後の最初のステートメントが実行されたときに準備されるスナップショットです。スナップショットを準備する方法は、現在のトランザクションのバージョン番号を記録することです。データはコピーされません。トランザクションのバージョン番号や隠しフィールドがわからない場合は、MySQL の MVCC を参照してください)。その後、このトランザクションの後続のすべてのデータ読み取りはこのスナップショットから読み取られるため、繰り返し不可能な読み取りは発生しませんが、ファントム読み取りは発生する可能性があります。つまり、スナップショット テーブルのデータは読み取り時には変更されませんが、更新などの書き込み操作中の更新数は予想される数と異なる場合があります。図のように

​​ インターフェース 1 でレコードが挿入され、送信された後、インターフェース 2 はトランザクションの開始時にスナップショット テーブルから読み取られるため、送信されたデータをまだ読み取ることができないことがわかります。したがって、当然読み取ることはできません。ただし、更新操作を実行すると、予期しないレコードが更新されます。これはファントム リード現象です。

シリアル化可能: トランザクションは 1 つずつ処理される必要があります。トランザクションで読み取り操作が実行されると、他のトランザクションはトランザクションが完了するまで読み取り操作のみを実行できます。書き込み操作が実行されると、他のトランザクションの操作は待機します (現在のトランザクションがコミットされるまで)。このレベルでは、ダーティ リード、反復不可能なリード、ファントム リードなどの現在の現象を防ぐことができます。図のように

上の図は、トランザクションが読み取り中の場合、他のトランザクションは書き込みができないことを示しています。下の図は、書き込み中の場合は操作できないことを示しています。

3 3 つの問題 - ダーティ リード、非反復リード、ファントム リード。

これらは、トランザクションの異なる分離レベルを採用することによって発生する可能性がある問題の一部です。分離レベルについては上で説明しましたが、混乱を避けるために個別に説明します。

  • ダーティ リード: 他のトランザクションによってコミットされていないトランザクション内のダーティ データを読み取ることを指します。これは、読み取り未コミット レベルで発生します。
  • 反復不可能な読み取り: トランザクション内の同じクエリでも、コミットされていない読み取りレベルとコミットされた読み取りレベルで結果が異なる場合があります。 (個人的には、非反復性というものを理解する必要はないと思います。混乱しやすいです)
  • ファントム リード: トランザクションで書き込み操作を実行すると、変更の数が予想される数と異なります。たとえば、以前はクエリできなかったデータが変更されます。

​​ 非反復読み取りとファントム読み取りの違いを説明します。非反復読み取りは、そのレコードのフィールド値の変更として理解できます。たとえば、ID 1 のレコードの name の 2 つの値が異なります。一方、ファントム読み取りは数量の違いです。たとえば、クエリを実行すると、合計 2 つのレコードがありますが、変更操作を実行すると、3 つのレコードが更新されます。

以上がMySQLトランザクションの特性と分離レベルの詳細です。MySQLトランザクションの特性と分離レベルの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL トランザクション分離レベルとロックメカニズムの問題に関する深い理解
  • MySQL トランザクション分離はどのように実現されますか?
  • MySQL シリーズ 10 同時実行制御を実装するための MySQL トランザクション分離
  • MySQL トランザクション分離レベルと MVCC の詳細な説明
  • MySQLトランザクションとSpring分離レベルの実装原理の詳細な説明
  • MySQL トランザクション分離レベルの原則例分析
  • Mysql トランザクション分離レベルの読み取りコミットの詳細な説明
  • MySQL トランザクション分離レベルの詳細

<<:  Vueナンバープレート検索コンポーネントの使い方の詳しい説明

>>:  Linux telnetコマンドの使用

推薦する

MySQL 8.0.16 圧縮版のダウンロードと Win10 システムへのインストール チュートリアル

公式サイトからダウンロード: https://www.mysql.com MySQLの公式サイトにア...

MySQL ストアド プロシージャの使用例の分析

この記事では、MySQL ストアド プロシージャの使用方法について説明します。ご参考までに、詳細は以...

複数の画像を切り替えるJavaScript

この記事では、複数の画像を切り替えるJavaScriptの具体的なコードを参考までに紹介します。具体...

CentOS 7 での Docker プロキシの設定 (Linux での Systemd サービスの環境変数設定)

Docker デーモンは、 HTTP_PROXY 、 HTTPS_PROXY 、およびNO_PRO...

Vue の計算プロパティの紹介

目次1. 計算プロパティとは何ですか? 2. 計算プロパティの構文3. 例1. 計算プロパティとは何...

nginx 設定ファイルパスとリソースファイルパスを表示する方法

nginx 設定ファイルのパスを表示する nginx -t 経由nginx -t コマンドの本来の機...

docker を使用して influxdb と mongo をデプロイするための一般的なコマンド

Docker ベースのデータベースをデプロイするsudo docker pull influxdb ...

自動ウェブページ更新と自動ジャンプのサンプルコード

ウェブページの自動更新: <head></head> の間に次のコードを追加...

MySQLがbinlogファイルを手動で登録し、マスタースレーブ異常を引き起こす理由

1. 問題の原因友人の @水米田 から、POSITION に基づくマスタースレーブについて質問があり...

HTML DOM入門_PowerNode Javaアカデミー

DOMとは何ですか? JavaScript を使用すると、HTML ドキュメント全体を再構築できます...

背景のグラデーションと自動フルスクリーンを実現するCSSコード

背景グラデーションと自動フルスクリーンに関する CSS の問題編集長は CSS の開発中に致命的な問...

MySQL 8.0 redo ログの詳細な分析

目次序文REDOログの生成REDOログ送信REDOログの保存と通知ユーザースレッドに通知要約する序文...

Docker を使用して Nginx+Flask+Mongo アプリケーションをデプロイする

サーバーにはNginx、データベースサポートにはMongo、Python言語のWebフレームワークに...

MySQL データベースの show processlist コマンドの使用の分析

実際のプロジェクト開発では、多数のクエリや挿入、特にマルチスレッド挿入など、データベースに大きな負荷...