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 を起動後に自動的にコマンドを実行する方法

推薦する

MySQL の DOS ウィンドウの文字化け問題を解決する方法

文字化けしたコードの問題は次のとおりです。 この問題の原因は非常に単純です。コマンドラインのエンコー...

簡潔なReactコンポーネントを書くためのヒント

目次スプレッド演算子を使用してプロパティを渡すのは避けてください関数パラメータをオブジェクトにカプセ...

CSS でショートカット プロパティを記述する際は、トラブルの順序に注意してください (落とし穴を避けるため)

ショートハンドプロパティは、複数のプロパティに同時に値を割り当てるために使用されます。たとえば、fo...

Centos8 で NIS ドメイン サービスをセットアップおよび構成するための詳細な手順

目次NIS の紹介ネットワーク環境: 1. 環境の準備(両方のノードが必要) 2.nisマスターサー...

nginx ロードバランシングを介して https にリダイレクトする方法

ウェブ上で証明書とキーをコピーするscp -rp -P52113 /application/ngin...

Linuxでawkを使用する方法の詳細な説明

awk を学ぶ前に、sed、grep、tr、cut などのコマンドを学んでおく必要があります。これら...

JavaScript の遅延読み込み属性パターンを理解する

従来、開発者はインスタンスで必要になる可能性のあるデータに対して JavaScript クラス内にプ...

Vue はファジークエリを実装します - MySQL データベースデータ

目次1. 需要2. 実装3. 結果1. 需要入力ボックスにデータを入力し、入力結果に基づいてデータベ...

CocosCreatorでWeChatゲームを作成する方法

目次1. WeChatパブリックプラットフォームからWeChat開発者ツールをダウンロードする2. ...

ツリー チャートの実装方法に関する Echarts チュートリアル

ツリーマップは主にツリーのようなデータ構造を視覚化するために使用され、特殊なタイプの階層です。これを...

MYSQLパターンマッチングREGEXPの使用に関する一般的な話など

のようにLIKE ではデータ全体が一致する必要がありますが、REGEXP では部分的な一致のみが必要...

Nginx リバース プロキシはポート 80 のリクエストを 8080 に転送します

まず、一連の概念を理解しましょう。nginx リバース プロキシとは何でしょうか?リバース プロキシ...

geoip を使用して nginx で地域を制限する方法

このブログは仕事のメモです環境: nginx バージョン: nginx/1.14.0 Centos ...

CentOS7 システムでスワップを増やす方法の例

序文スワップは、ディスク上にある「仮想メモリ」の一部である特殊なファイル (またはパーティション) ...

js メモリ リークのシナリオ、それらを詳細に監視および分析する方法

目次序文どのような状況でメモリリークが発生する可能性がありますか? 1. 偶発的なグローバル変数2....