MySQL トランザクション制御フローと ACID 特性

MySQL トランザクション制御フローと ACID 特性

1. ACIDの特性

トランザクション処理は、バッチで実行する必要がある MySQL 操作の管理メカニズムです。トランザクション中に、操作のバッチ全体が正しく実行されない限り、途中の操作が失敗すると、システム データに誤った変更が加えられないように、元の安全な状態に回滾(Rollback)ます。

MySQL 5.5 以降、デフォルトのストレージ エンジンが MyLSAM から InnoDB に置き換えられました。その重要な理由の 1 つは、InnoDB がトランザクションをサポートしていることです。SHOW SHOW ENGINESを使用して、MySQL のさまざまなストレージ エンジンの説明を見てみましょう。

トランザクションの最も重要な 4 つのプロパティは、 ACIDプロパティと呼ばれることがよくあります。
A - Atomicity 原子性:トランザクションは分割できない最小単位です。トランザクション内のすべての操作は、中間状態を経ることなく、成功するか失敗するかのいずれかになります。アトミック性は主にトランザクションログ内のロールバックログ(undoログ)によって実現されます。トランザクションがデータベースを変更すると、InnoDBは操作に基づいて反対の操作のundoログを生成します。たとえば、挿入操作の場合は削除レコードが生成されます。トランザクションが失敗した場合やロールバックが呼び出された場合は、undoログの内容に基づいて実行前の状態に復元されます。

C - Consistency 一致性:トランザクションの実行前と実行後のデータは、合法かつ一貫した状態にあります。例外が発生しても、一意性制約などのデータベースの整合性制約は、例外によって破壊されることはありません。

I - Isolation 隔離性:各トランザクションは互いに独立しており、他のトランザクションの実行による影響を受けません。トランザクションは、コミットされるまで他のトランザクションからは見えません。分離はトランザクション分離レベルによって定義され、書き込み操作の分離を保証するためにロック メカニズムが使用され、読み取り操作の分離を保証するために MVCC が使用されます。これについては後で詳しく説明します。

D - Durability 持久性:トランザクションがコミットされた後のデータの変更は耐久性があり、データベースがクラッシュしても失われません。これは、トランザクション ログ内の再実行ログによって保証されます。トランザクションが変更される前に、変更情報が REDO ログに事前に書き込まれます。データベースがクラッシュした場合は、リカバリ後に REDO ログのレコードが読み取られ、データが復元されます。

トランザクション制御構文

MySQL トランザクション制御には、トランザクションの開始、コミット、ロールバック、保存ポイントなど、いくつかの重要なノードがあります。

トランザクションを開始するということは、トランザクションの実行が開始されることを意味し、ステートメントはSTART TRANSACTIONまたはBEGINです。トランザクションをコミットすると、トランザクション内のすべての更新がディスク上の物理データベースに書き込まれます。トランザクションはCOMMITで正常に終了します。例外が発生し、ロールバックが必要な場合は、ステートメントはROLLBACKです。一度コミットされたトランザクションはロールバックできないことに注意してください。したがって、コード実行中に例外が発生した場合は、コミットではなくロールバックを直接実行する必要があります。

たとえば、A が B に 100 元を送金する場合:

// 通常どおり実行して送信します BEGIN; # トランザクションを開始します UPDATE account_balance SET balance = balance - 100.00 WHERE account_name = 'A';
account_balance を更新し、balance = balance + 100.00 に設定します。WHERE account_name = 'B';
COMMIT; # トランザクションをコミット // 例外が発生したのでロールバック BEGIN; # トランザクションを開始 UPDATE account_balance SET balance = balance - 100.00 WHERE account_name = 'A';
account_balance を更新し、balance = balance + 100.00 に設定します。WHERE account_name = 'B';
ROLLBACK; # トランザクションのロールバック

複雑なシナリオでは、操作全体をロールバックする必要はなく、バッチで実行して特定のノードにロールバックする必要がある場合もあります。これは、大規模なトランザクションの下に複数のサブトランザクションをネストすることと同じです。MySQL では、 SAVEPOINT使用してこれを実現できます。

始める;
user_tbl(id)値に挿入する(1);
user_tbl(id)値に挿入する(2)
ROLLBACK; # 1,2 BEGIN を記述しないでください。
user_tbl(id)値に挿入する(1);
セーブポイント s1;
user_tbl(id)値に挿入する(2)
ROLLBACK TO s1; # 保持ポイント s1 にロールバックし、1 が正常に書き込まれ、2 がロールバックされ、最終結果は 1 になります。

RELEASE SAVEPOINT s1; # セーブポイントを解放する

ちなみに、トランザクションには、暗黙的トランザクション (自動的にコミットされる) と明示的トランザクション (手動でコミットする必要がある) の 2 種類があります。MySQL では、暗黙的トランザクションがデフォルトになっています。暗黙的トランザクションは自動的にコミットされ、 autocommitパラメータによって制御されます。

# 変数を表示する SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| 変数名 | 値 |
+---------------+-------+
| 自動コミット | オン |
+---------------+-------+
# 自動コミットを有効にする(デフォルト)
自動コミットを 1 に設定します。
# 自動コミットをオフにする SET autocommit = 0;

自動コミット状態では、トランザクションが明示的に開かれていない場合、各 DML ステートメントはトランザクションであり、システムは各 SQL ステートメントに対してコミット操作を自動的に実行します。 BEGIN または START TRANSACTION を使用してトランザクションを開始した後、COMMIT または ROLLBACK を使用してトランザクションを終了するまで自動コミットは無効のままになり、終了した時点で自動コミット モードは以前の状態に復元されます。

completion_type,デフォルト値は0(NO_CHAIN)です。

# 変数を表示する SHOW VARIABLES LIKE 'completion_type';
+-----------------+----------+
| 変数名 | 値 |
+-----------------+----------+
| 完了タイプ | NO_CHAIN ​​|
+-----------------+----------+

completion_type = 0: デフォルト値。コミットが実行された後、新しいトランザクションは自動的に開始されません。
completion_type = 1: コミットを実行すると、COMMIT AND CHAIN を実行するのと同等となり、同じ分離レベルでトランザクションを自動的に開始します。
completion_type = 2: コミットを実行する場合、COMMIT AND RELEASE を実行するのと同等です。トランザクションがコミットされると、サーバー接続は自動的に切断されます。

3. トランザクション同時実行例外

実際の生産ライン環境では、大規模な同時リクエストが発生する場合があります。トランザクション分離レベルが適切に設定されていない場合、いくつかの異常な状況が発生する可能性があります。最も一般的な異常は臟讀(Dirty Read)、幻讀(Phantom Read)および不可重復讀(Unrepeatable Read)。

1. ダーティリード

ダーティ リードとは、次のように、トランザクションが別のトランザクションのコミットされていないデータにアクセスすることを意味します。

  • a の値が 1 で、トランザクション 2 によって a が 2 に変更されたとします。この時点では、トランザクションはまだコミットされていません。
  • このとき、トランザクション 1 は a を読み取り、a の値は 2 です。トランザクション 1 は読み取りを完了します。
  • その結果、トランザクション 2 は a への変更をロールバックし (またはコミットせず)、a の値は 1 に戻ります。
  • この結果、a の値は 1 になりますが、トランザクション 1 によって取得された結果は 2 になるため、トランザクション 1 はダーティ データを読み取り、ダーティ リードが発生します。

2. 繰り返し不可能な読み取り

反復不可能な読み取りとは、同じデータを複数回読み取るトランザクション中にデータ値の内容が変化し、同じ値を読み取ることができなくなる状況を指します。次のプロセスに示すように、同じデータが更新/削除される現象を表します。

  • トランザクション1はaを読み取り、a = 1
  • このとき、トランザクション 2 は a を 2 に変更して正常に送信され、変更が有効になります。
  • トランザクション1は再びaを読み取り、今度はa = 2となる。
  • トランザクション 1: 同じトランザクションで同じ値が 2 回読み取られますが、データ値の内容が変更されているため、繰り返し不可能な読み取りが発生します。

3. ファントムリーディング

ファントム リードとは、トランザクション中に同じデータを複数回読み取る際に、データ項目の数が変化するという、錯覚が起こったような状況を指します。次のプロセスに示すように、テーブル全体に対する挿入/削除の現象を指します。

  • トランザクション1は初めて数量を読み取り、10個のデータ項目を取得します。
  • このとき、トランザクション 2 はデータを挿入し、正常に送信します。変更が有効になり、データは 11 になります。
  • トランザクション 1 は、再び数字を読み取り、11 個のデータを取得します。トランザクション 1 では、何の理由もなく、まるで錯覚のように、もう 1 個のデータがあります。ファントム リードが発生します。

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

シリアル化されたトランザクション処理は、もちろん最も安全な方法ですが、シリアル化ではデータベースへの高同時アクセスのニーズを満たすことができません。妥協案として、トランザクションの同時性と引き換えにデータベースの分離基準を下げる必要があり、効率性の向上と引き換えに制御可能な範囲内での正確性を犠牲にすることがあります。このトレードオフは、トランザクションの分離レベルによって実現されます。

データベースには、低から高の順に、讀未提交Read Uncommitted讀已提交Read Committed可重復讀Repeatable Read 、および串行化Serializable 4 つのトランザクション分離レベルがあります。

(1)コミットされていない読み取り
コミットされていないコンテンツの読み取りを許可します。このレベルのクエリはロックされないため、ダーティ リード、反復不可能なリード、ファントム リードが発生する可能性があります。
(2)コミットされた読み取り
コミットされたコンテンツのみ読み取りが許可されます。ダーティ データはコミットされていないデータであり、読み取られないため、このレベルのクエリではダーティ リードは発生しません。ただし、反復不可能な読み取りとファントム リードは発生する可能性があります。
(3)繰り返し読み取り(MySQLのデフォルトの分離レベル)
行レベルのロックを使用して、同じクエリ条件での 2 つのクエリによって取得されたデータ結果の一貫性を保証すると、ダーティ リードと非反復読み取りを回避できますが、ファントム リードを回避する方法はありません。
(4)シリアル化可能
テーブル レベルのロックを使用してすべてのトランザクションのシリアル化を保証すると、すべての異常な状況を防ぐことができますが、システムの同時実行性が犠牲になります。

上記3つの異常事態に対する4つの隔離レベルにおける許容範囲は以下のとおりです(代表者は、禁止を表します):

分離レベルを表示するコマンドは次のとおりです。

'transaction_isolation' のような変数を表示します。
# または SELECT @@global.tx_isolation, @@tx_isolation;

2 番目の方法は、グローバルおよび現在のセッション分離レベルを表示することです。

分離レベルを設定するコマンドは次のとおりです

# 現在のセッションの分離レベルをコミットされていない読み取りに設定します SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
# グローバル分離レベルをコミットされていない読み取りに設定します SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 

MySQL トランザクションの詳細な説明については、これで終わりです。MySQL に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL はどのようにしてマルチバージョンの同時実行性を実現するのでしょうか?
  • MySQLフィルタリングレプリケーションのアイデアの詳細な説明
  • MySQL 外部キー (FOREIGN KEY) の使用例の詳細な説明
  • MySQL のストアド プロシージャを使用して 100 万件のレコードをすばやく生成する方法
  • Pythonインターフェース自動化はpymysqlデータベース操作プロセスを簡単に分析します
  • MySQLはストアドプロシージャを使用して数百万のデータを素早く追加します。サンプルコード
  • MySQL で重複時間を削除して時間差を計算する実装
  • MySQL データベースでは、datetime、bigint、timestamp を使用して時間の選択を表します。時間を保存するのに最も効率的なのはどれですか?
  • MySQL グローバルロックとテーブルレベルロックの具体的な使用法
  • Redo ログと Undo ログに基づく MySQL クラッシュ回復の分析

<<:  Nginx サービスを使用してサブドメイン環境を構築し、2D マップの読み込みパフォーマンスを向上させる方法を説明します。

>>:  デザインにおけるユーザーエクスペリエンスの背後にある8つのユーザー本能について話す

推薦する

CentOS 6.5 の設定 ssh キーフリーログインで pssh コマンドを実行する方法の説明

1. psshを確認してインストールします。yum list pssh 2. キーレスログインが設定...

MySQLでJSONフィールドを操作する方法

MySQL 5.7.8 では json フィールドが導入されました。このタイプのフィールドは使用頻度...

MySql 組み込み関数の自習知識ポイントまとめ

文字列関数文字ascii(str)のASCIIコード値をチェックし、strが空の文字列の場合は0を返...

Windows Server 2016 でサービスを展開する方法 (グラフィック チュートリアル)

導入インストールするシステムの数が多い場合、USB フラッシュ ドライブまたは CD を使用した手動...

Linux でのプロセスデーモン スーパーバイザーのインストール、構成、および使用

Supervisor は非常に優れたデーモン管理ツールです。自動起動、ログ出力、自動ログカットなど、...

Ubuntu 20.04 ファイアウォール設定の簡単なチュートリアル (初心者)

序文ますます便利になった今日のインターネット社会では、さまざまなインターネット ランサムウェア ウイ...

MySQL デッドロックのトラブルシューティング プロセスの完全な記録

序文これまで遭遇したデータベースのデッドロックはすべて、バッチ更新中のロック順序の不一致が原因でした...

Webpack3+React16コード分割の実装

プロジェクトの背景最近、webpackのバージョンが古いプロジェクトがあります。 リーダー層では今の...

nginx でディレクトリ ホワイトリストと IP ホワイトリストを設定する方法

1. ディレクトリホワイトリストを設定する:指定されたリクエストパスに制限を設定しないでください。た...

mysql-8.0.16 winx64 最新インストール チュートリアル (画像とテキスト付き)

最近、データベースについて学び始めました。最初にやったことは、データベースとは何か、データベースとデ...

Vue での this.$set の動的データバインディングのケーススタディ

インターネット上の this.$set の説明はわかりにくいと感じます。単一データ、オブジェクト、配...

MySQLが大量のデータを処理する際にクエリ速度を最適化するいくつかの方法

実際に参加したプロジェクトでは、MySQL テーブルのデータ量が数百万に達すると、通常の SQL ク...

MySQL トランザクション制御フローと ACID 特性

目次1. ACIDの特性トランザクション制御構文3. トランザクション同時実行例外1. ダーティリー...

MySQL パスワードは正しいが、ローカルにログインできない -1045

MySQLパスワードは正しいが、ローカルでログインできない -1045 ユーザー 'roo...

MySQL MHA 操作ステータス監視の概要

目次1. プロジェクトの説明1.1 背景1.2 実装設計1.2.1 従来の方法1.2.2 最適化され...