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

推薦する

Linux での MySQL 8.0 インストール チュートリアル

この記事では、LinuxでMySQL 8.0をインストールする方法を紹介します。具体的な内容は次のと...

nginx を介して方向プロキシを実装するプロセスの図

この記事は主に、nginx を介して方向プロキシを実装するプロセスを紹介します。この記事のサンプル ...

JS がビデオ弾幕効果を実現

これを実現するには、ES6 モジュール開発とオブザーバー モードを使用します。オブザーバー パターン...

Docker コンテナ ソース コードのデプロイ httpd ストレージ ボリュームを使用して Web サイトをデプロイする (推奨)

目次Dockerコンテナのソースコードを使用してhttpdをデプロイし、ストレージボリュームを使用し...

React の 10 個のフックの紹介

目次ReactHook とは何ですか? Reactは現在フックを提供している1. 使用状態2.use...

Xmeter APIインターフェーステストツールの使用状況の分析

XMeter API は、以下のサービスを含む、JMeter に基づくワンストップのオンライン イン...

CentOS 7.4 で MySQL 5.7.28 バイナリモードをインストールする方法

Linuxシステムバージョン: CentOS7.4 MySQL バージョン: 5.7.28 Linu...

Linux ログ表示方法 6 つのまとめ

バックエンド プログラマーは、さまざまな場所で Linux を扱います。Linux ログの読み方がわ...

MySQL InnoDBセカンダリインデックスのソート例の詳細な説明

ソート問題最近、Geek Time の「45 Lectures on MySQL Practice」...

Docker コンテナにおける Patroni の簡単な分析

目次イメージの作成ファイル構造Dockerファイルエントリポイント関数ファイルを生成するイメージを構...

MySQL クエリ ステートメントのプロセスと EXPLAIN ステートメントの基本概念とその最適化

ウェブサイトやサービスのパフォーマンスは、データベースの設計(適切な言語開発フレームワークを選択した...

Nginx Linux のインストールと展開の詳細なチュートリアル

1. Nginx の紹介Nginxは負荷分散やリバースプロキシにも使えるWebサーバーです。現在最も...

Linux環境変数の設定戦略の詳細な説明

ソフトウェアのインストールをカスタマイズする場合、多くの場合、環境変数を設定する必要があります。以下...

LinuxにMySQLをインストールし、外部ネットワークアクセスを構成する例

設定手順1. DNSが設定されているかどうかを確認するDNSが設定されていない場合は、前の記事を参照...

Vue.js スタイルレイアウト Flutter ビジネス開発共通スキル

シャドウスタイルにおけるフラッターとCSSの対応UIによって指定されたCSSスタイル 幅: 75px...