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コマンドの使用

推薦する

WeChatミニプログラムで検索キーワードを強調表示するサンプルコード

1. はじめにプロジェクトで要件に遭遇したら、データを検索してキーワードを強調表示します。要件を受け...

WeChat アプレット計算機の例

この記事では、参考までに、計算機を実装するためのWeChatアプレットの具体的なコードを紹介します。...

HTML 画像 img にハイパーリンクを追加した後の醜い青い境界線の問題を解決する

HTML画像にハイパーリンクを追加すると醜い青い枠線が表示される次のように:解決: CSS スタイル...

Tomcat で JNDI データ ソースを構成する 3 つの方法

これまでの仕事では、開発サーバーは一般的にTomcatでした。データソースは、多くの場合、appli...

MySQL のロックに関する問題

ロックの分類:データ操作の粒度から:テーブルロック:操作時にテーブル全体がロックされます。行ロック:...

DockerコンテナでLNMPをコンパイルする例

目次1. プロジェクトの説明2. Nginxイメージの作成3. MySQLイメージの作成4. PHP...

MySQL 文字列分割の例 (区切り文字なしの文字列抽出)

区切り文字なしの文字列抽出質問の要件データベース内のフィールド値:実装効果: 1行のデータを複数行に...

カラフルな時計効果を実現する JavaScript キャンバス

キャンバスを使ってカラフルな時計を書いてみよう! 1. タイトル(1)時計のケースが与えられ、ページ...

Mac M1 での Nginx のマルチサイト構成の実装

注: nginxはbrew経由でインストールされますウェブサイトのルートディレクトリ: /opt/h...

MySQLクエリのパフォーマンスに影響を与える大きなオフセットの理由と最適化の詳細な説明

序文MySQL クエリは select コマンドを使用し、limit および offset パラメー...

Vite と Vue CLI の長所と短所

Vue エコシステムには Vite と呼ばれる新しいビルド ツールがあり、Vue CLI よりも 1...

MySQL での limit の使用方法は何ですか (推奨)

SELECT * FROM テーブル名制限m,n; SELECT * FROM テーブル LIMI...

初心者のための入門チュートリアル⑤:ウェブサイト登録はとても簡単、簡単な登録のヒント

スペースを購入してウェブサイトを構築したことがある友人なら、ウェブサイトは正式に開設する前に登録する...

MYSQL の binlog 最適化に関する考察の要約

質問質問 1: トランザクションをコミットするときに REDO ログをフラッシュすることによって発生...

MySQLでTEXT/BLOB型を使用する際の注意点を詳しく説明します

1. TEXTとBLOBの違いTEXT ファミリと BLOB ファミリの唯一の違いは、BLOB 型は...