Mysqlトランザクション処理の詳細な説明

Mysqlトランザクション処理の詳細な説明

1. MySQLのトランザクションの概念

MySQL トランザクションは主に、操作量が多く複雑度の高いデータを処理するために使用されます。論理実行単位は、1 つまたは複数のデータベース操作のシーケンスで構成されます。この一連の操作は、完全に実行されるか、または中止されます。 MySQL では、Innodb データベース エンジンを使用するデータベースまたはテーブルのみがトランザクションをサポートします。トランザクションは、挿入、更新、および削除ステートメントを管理するために使用されます。

2. トランザクション特性:原子性、一貫性、独立性、永続性。これら 4 つの特性は、ACID プロパティとも呼ばれます。

1. 原子性: トランザクションは、アプリケーション内の最小の実行単位です。これは、原子が自然界の最小の粒子であり、分割できないという特性を持っているのと同じです。トランザクションは、アプリケーション内の最小の分割不可能な論理実行単位です。トランザクションのグループは、成功するか取り消されるかのいずれかになります。

2. 安定性と一貫性: トランザクション実行の結果、データベースは 1 つの一貫した状態から別の一貫した状態に変更される必要があります。正常にコミットされたトランザクションの結果のみが含まれている場合、データベースは一貫した状態にあります。一貫性は原子性によって保証されます。不正なデータ(外部キー制約など)がある場合、トランザクションは取り消されます。

3. 分離: 各トランザクションの実行は互いに干渉せず、トランザクションの内部操作は他の同時実行トランザクションから分離されます。つまり、同時に実行されたトランザクションは互いの中間状態を認識できず、同時に実行されたトランザクションは互いに影響を与えることができません。トランザクションは独立して実行されます。トランザクションの結果が他のトランザクションに影響を与える場合、他のトランザクションは取り消されます。トランザクションを 100% 分離するには、速度を犠牲にする必要があります。

4. 永続性と信頼性: 永続性は永続性とも呼ばれ、トランザクションがコミットされると、データに加えられた変更は永続的なストレージに記録され、通常は物理データベースに保存されることを意味します。ソフトウェアまたはハードウェアがクラッシュすると、InnoDB データ テーブル ドライバーはログ ファイルを使用してファイルを再構築および変更します。信頼性と高速性を同時に実現することはできません。innodb_flush_log_at_trx_commit オプションは、トランザクションがログに保存されるタイミングを決定します。

注意: ストレージ エンジン MyISAM はトランザクションをサポートしていませんが、ストレージ エンジン InnoDB はトランザクションをサポートしています。トランザクションは、データに影響を与えるステートメントに対してのみ有効です。 show engines MySQL ロックでサポートされているデータ エンジンを表示します。

3. データの概念の読み取り

1. ダーティ リード: ダーティ リードはダーティ データの読み取りであり、ダーティ データとはコミットされていないデータのことです。トランザクションはレコードを変更しています。トランザクションが完了してコミットされるまで、データは保留状態にあります (コミットまたはロールバックされる可能性があります)。この時点で、2 番目のトランザクションはコミットされていないデータを読み取り、それに基づいてさらに処理を実行し、コミットされていないデータの依存関係を生成します。この現象はダーティリードと呼ばれます。

2. 非反復読み取り: トランザクションは同じレコードを 2 回読み取りますが、2 回読み取られるデータは異なります。これを非反復読み取りと呼びます。つまり、このトランザクションの 2 回の読み取りの間に、他のトランザクションによってデータが変更されます。

3. ファントム リード: トランザクションは、同じクエリ条件に従って以前に取得したデータを再読み取りしますが、他のトランザクションがそのクエリ条件を満たす新しいデータを挿入していることを検出します。この現象はファントム リードと呼ばれます。

4. トランザクション分離レベル

トランザクション分離レベルの構文を変更します。
[セッション | グローバル] トランザクション分離レベルの設定 {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

1. コミットされていないデータの読み取り (無許可の読み取り、コミットされていないデータの読み取り): これは最も低い分離レベルであり、他のトランザクションがコミットされていないデータを参照できるようにします。このレベルではダーティ リードが発生する可能性があります。トランザクションがデータの書き込みを開始した場合、別のトランザクションは同時に書き込むことはできませんが、他のトランザクションはこのデータ行を読み取ることができます。この分離レベルは、排他的書き込みロックを通じて実現できます。これにより更新の損失は回避されますが、ダーティ リードが発生する可能性があります。つまり、トランザクション B はトランザクション A がコミットしていないデータを読み取ります。 SELECT 文は非ロック方式で実行されるため、ダーティデータを読み取ることが可能です。分離レベルは最低です。

SET セッション トランザクション分離レベルはコミットされていない読み取りです。
SET グローバル トランザクション分離レベル 読み取り未コミット;/* グローバルでは使用しないことを推奨 */
@@global.tx_isolation を選択します。
@@session.tx_isolation を選択します。
@@tx_isolation を選択します。

シンプルな学生テーブルを作成し、ID、名前、および数値フィールドを設定し、トランザクション 1 を開始し、テーブルにストアド プロシージャを追加し、トランザクションをコミットしません。現在のデータベース トランザクション ステータスを確認すると、トランザクション レベルが READ UNCOMMITTED のデータ トランザクションを確認できます。

学生が存在する場合はテーブルを削除します。
テーブル学生を作成(
id int 主キー 自動増分 コメント 'id',
名前 varchar(100) コメント '名前',
数値整数
);
proc_on_sw が存在する場合はプロシージャを削除します。
デリミタ;;
プロシージャ proc_on_sw() を作成する
始める
トランザクションを開始します。
学生(名前、番号)に値('aaa'、1)を挿入します。
information_schema.INNODB_TRX から * を選択します。
終わり
;;
デリミタ;;
proc_on_sw() を呼び出す;

新しいトランザクション 2 を作成し、学生テーブルをクエリします。READ UNCOMMITTED レベルでは、他のトランザクションのコミットされていないデータを確認できます。データベース トランザクションのステータスを再度確認すると、ステータスが正常であることがわかります。

トランザクションを開始します。
学生から*を選択します。
専念;
information_schema.INNODB_TRX から * を選択します。

2. 読み取りコミット (承認済み読み取り、読み取りコミット): データを読み取るトランザクションは、他のトランザクションが引き続きデータ行にアクセスできるようにしますが、コミットされていない書き込みトランザクションは、他のトランザクションが行にアクセスすることを禁止します。この分離レベルではダーティ リードは回避されますが、繰り返し不可能なリードが発生する可能性があります。トランザクション A が事前にデータを読み取り、トランザクション B がすぐにデータを更新してトランザクションをコミットし、トランザクション A が再度データを読み取ると、データが変更されていました。

SET セッション トランザクション分離レベルの読み取りコミット;
SET グローバル トランザクション分離レベル read committed; /* グローバルでは使用しないことを推奨 */

proc_on_up が存在する場合はプロシージャを削除します。
デリミタ;;
プロシージャ proc_on_up() を作成する
始める
自動コミットを0に設定します。
学生セット名を 'cc' に設定し、ID を 1 にして更新します。
専念;
自動コミットを1に設定します。
終わり
;;
デリミタ;;
proc_on_up() を呼び出す;
学生から*を選択します。


3. 繰り返し読み取り: データが読み取られると (トランザクションが開始されると)、変更操作は許可されなくなります。トランザクションが開始されると、他のトランザクションの UPDATE 変更操作は許可されません。繰り返し不可能な読み取りは、変更、つまり UPDATE 操作に対応します。しかし、ファントム リードの問題がまだ発生する可能性があります。ファントム リード問題は UPDATE 操作ではなく INSERT 操作に対応するためです。反復不可能な読み取りとダーティ読み取りは回避されますが、ファントム読み取りが発生する場合があります。これは、「共有読み取りロック」と「排他的書き込みロック」によって実現できます。

set session transaction isolation level repeatable read;

4. シリアル化とシリアライゼーション: 厳密なトランザクション分離を提供します。トランザクションはシリアルに実行する必要があります。トランザクションは 1 つずつしか実行できず、同時に実行することはできません。 「行レベルのロック」だけではトランザクションのシリアル化を実現できない場合は、クエリ操作を実行したばかりのトランザクションによって新しく挿入されたデータにアクセスされないようにするために、他のメカニズムを使用する必要があります。シリアル化は最も高いトランザクション分離レベルですが、コストが最も高く、パフォーマンスが非常に低いため、ほとんど使用されません。このレベルでは、トランザクションは順番に実行されるため、ダーティ リードや反復不可能なリードだけでなく、ファントム リードも回避されます。

set session transaction isolation level serializable;

分離レベル ダーティリード 非反復リード ファントムリード コミットされていないリード はい はい はい
コミットされた読み取り NO YES YES
繰り返し読み取り いいえ いいえ はい
シリアル化 NO NO NO

5. コミットとロールバックを含む完全な例

pro_new が存在する場合はプロシージャを削除します。
デリミタ;;
プロシージャ pro_new(out rtn int) を作成します。
始める
err INT デフォルト 0 を宣言します。
-- 例外が発生した場合は自動的に処理され、ロールバックされます
sqlexception ROLLBACK の終了ハンドラを宣言します。 
-- トランザクションを開始します。autocommit=0 を設定します。
トランザクションを開始します。
学生(名前、数値)に値(NULL、2.3)を挿入します。
-- set err = @@IDENTITY; -- = 最後の挿入の自動増分 ID を取得します。
set err =last_insert_id(); -- 最後の挿入の自動増分 ID を取得します
学生(名前、番号)にVALUEs('ccc'、err)を挿入します。
-- 操作に異常がなければ、トランザクションをコミットします。
-- 戻り値を1に設定する
rtn=1 を設定します。
自動コミットを1に設定します。
終わり
;;
デリミタ;;
@n=1 を設定します。
pro_new(@n); を呼び出します。
@n を選択します。

以下もご興味があるかもしれません:
  • MySQL の 4 つのトランザクション分離レベルを例を使って分析する
  • Mysql トランザクション ログとログ ファイルが大きすぎて縮小できないという問題を解決します。
  • MySQL ストアド プロシージャ、カーソル、トランザクションの例の詳細な説明
  • PHP mysqli トランザクション操作の一般的な方法の分析
  • Mysqlトランザクション操作の失敗を解決する方法
  • MySQL の 4 つのトランザクション分離レベルの詳細な説明
  • NodeJs は MySQL モジュールを使用してトランザクション処理の例を実装します
  • MySQLデータベースのトランザクション分離レベルの詳細な説明
  • MySQLトランザクションの基本的な学習と経験の共有

<<:  ReactにおけるuseRefの具体的な使い方

>>:  DOSBox を起動後に自動的にコマンドを実行する方法

推薦する

HTML iframe と frameset の違い_PowerNode Java Academy

導入1.<iframe> タグ: iframe は、ページ内に内部フレームを生成するイン...

Vueの使用に関する深い理解

目次Vueのコアコンセプトを理解するVueの双方向バインディングの原理と実装を探るVue 双方向バイ...

JavaScript フロントエンドのタイムアウト非同期操作に最適なソリューション

目次コードの実行に長い時間がかかる場合はどうなりますか? Axiosにはタイムアウト処理機能が搭載さ...

Nest.js 環境変数の設定とシリアル化の詳細な説明

環境変数の設定の簡単な説明プログラムは、環境によって異なる環境変数を必要とします。たとえば、実稼働環...

MySQL インデックス データ構造の詳細な分析

目次概要インデックスデータ構造バイナリツリー赤黒木BツリーB+ツリーハッシュ索引InnoDB インデ...

スタイルを書く際の背景色宣言の重要性

タイトルの通り、ページを修正すると以下のような状況が発生する可能性があります。現在、古いページを改修...

Linux で crond ツールを使用してスケジュールされたタスクを作成する方法

序文Crond は Linux のスケジュール実行ツール (Windows のスケジュールされたタス...

innodb_autoinc_lock_mode の表現と値の選択方法についての簡単な説明

前提条件: Percona 5.6 バージョン、トランザクション分離レベルは RR mysql>...

Linux オペレーティング システムの概要と紹介

目次1. オペレーティングシステムとは何か2. Linuxの起源3. Linuxの基本機能4. Li...

docker イメージのプル速度が遅い問題の解決策

現在、Docker には中国向けの公式ミラーがあります。詳細については、https://www.do...

flex-grow、flex-shrink、flex-basis、9グリッドレイアウトを理解する

1. flex-grow、flex-shrink、flex-basis プロパティflex-grow...

MySQL 5.7.23 バージョンのインストールチュートリアルと設定方法

MySQL を自分でインストールするのに 3 時間かかりました。チュートリアルはたくさんあるにもかか...

preタグを自動的に折り返すためのサンプルコード

pre 要素は、フォーマット済みのテキストを定義します。 pre 要素で囲まれたテキストでは、通常、...

CSSスプライトの応用の詳細な説明

CSS Sprite は、CSS スプライトとも呼ばれ、画像結合技術です。この方法は、複数の小さなア...

Linux システムの仮想ホストで Swoole Loader 拡張機能を有効にする方法

特記事項: Swoole 拡張機能のみがインストールされ、サーバーはホストにインストールされません。...