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

推薦する

Ubuntu にグラフィック ドライバーが正常にインストールされたかどうかを確認する方法

次のコマンドを実行します: glxinfo | grep レンダリング結果が「はい」の場合、グラフィ...

node.js で PC 上の WeChat アプレット パッケージを復号化するための処理アイデア

目次アプレットのソースコードはどこにありますか? PC ミニプログラムはどのように暗号化されますか?...

2048 ゲームを実装するためのネイティブ js

2048ミニゲーム、参考までに具体的な内容は以下のとおりですまず、2048ゲームは16のグリッドか...

ページキャッシュを無効にするいくつかの方法を共有する

本日、開発中に、顧客からページをキャッシュしないように要求される方法に遭遇しました。調べたところ、ペ...

グローバルトーストコンポーネントをカプセル化するVueの完全な例

目次序文1. vue-cliを使う1. Toastコンポーネントを定義する2. main.jsで設定...

HTML マークアップ言語 - フォーム

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

CSS3 疑似クラスセレクターの簡単なレビュー

序文CSS がフロントエンド開発の基本的なスキルであるならば、「セレクター」は基礎中の基礎です。これ...

最も完全なpackage.json分析

目次1. 概要2. 名前フィールド3. バージョンフィールド4. 説明フィールド5. キーワードフィ...

MySQL 5.7 における基本的な JSON 操作ガイド

序文プロジェクトのニーズにより、ストレージ フィールドは JSON 形式で保存されます。プロジェクト...

Vue ファースト スクリーン パフォーマンス最適化コンポーネントの知識ポイントの概要

Vue ファースト スクリーン パフォーマンス最適化コンポーネントVue ファースト スクリーン パ...

Nginx ロードバランシング/SSL 構成の実装

負荷分散とは何ですか?ドメイン名が複数の Web サーバーを指している場合は、nginx ロード バ...

Linux での Jenkins の詳細なインストール手順

目次1. JDKをインストールする2. Jenkinsをインストールする3. Jenkinsの設定を...

MySQL で自動インクリメントシーケンスを実装するためのサンプルコード

1. シーケンステーブルを作成する テーブル `sequence` を作成します ( `name` ...

WeChatアプレットがジグソーパズルゲームを実装

この記事では、WeChatアプレットでジグソーパズルゲームを実装するための具体的なコードを参考までに...