mysql データベース トランザクションの概念と特性、および MySQL でトランザクションを実行する構文とプロセス

データベーストランザクションの概念と特性

データベーストランザクションとは、一連のデータベース操作コマンドを含む仕組み、操作シーケンスです。トランザクションは、すべてのコマンド全体とともに操作リクエストをシステムに送信または取り消します。つまり、この一連のデータベース コマンドは実行されるか実行されないかのどちらかであるため、トランザクションは分割できない論理的な作業単位となります。

データベース システムで同時操作を実行する場合、トランザクションは最小の制御単位として使用されます。これは、複数のユーザーが同時に操作するデータベース システムに特に適しています。たとえば、航空会社の予約システム、銀行、保険会社、証券取引システムなどです。

トランザクションには、原子性、一貫性、分離性、耐久性という 4 つの特性があり、通常、これら 4 つの特性は ACID と呼ばれます。

1. 原子性

トランザクションは完全な操作です。トランザクションの要素は分割できません (アトミック)。トランザクション内のすべての要素は、全体としてコミットまたはロールバックする必要があります。トランザクション内のいずれかの要素が失敗すると、トランザクション全体が失敗します。

銀行振込トランザクションを例に挙げると、トランザクションが送信されると、2 つの口座のデータが更新されます。何らかの理由で両方のアカウントが正常に更新される前にトランザクションが終了した場合、両方のアカウントの残高は更新されず、アカウント残高への変更は元に戻され、トランザクションを部分的にコミットすることはできません。

2. 一貫性

トランザクションが完了すると、データは一貫した状態になる必要があります。つまり、データベースに保存されているデータは、トランザクションが開始される前は一貫した状態にあります。進行中のトランザクション中に、データが部分的に変更されるなど、データが不整合な状態になる可能性があります。ただし、トランザクションが正常に完了したら、データを既知の一貫した状態に再度戻す必要があります。トランザクションを通じてデータに加えられた変更によってデータが損傷したり、トランザクションによってデータ ストレージが不安定な状態になることはありません。

銀行振込取引を例に考えてみましょう。トランザクションが開始される前は、すべての口座残高の合計は一貫した状態にあります。取引の過程で、一方の口座の残高は減りますが、もう一方の口座の残高は変更されません。したがって、すべての口座残高の合計は一致しません。トランザクションが完了すると、アカウントの合計残高は再び一貫した状態に復元されます。

3. 隔離

データを変更するすべての同時トランザクションは互いに分離されています。つまり、トランザクションは独立している必要があり、他のトランザクションに依存したり影響を与えたりしてはなりません。データを変更するトランザクションは、同じデータを使用する別のトランザクションが開始される前、または同じデータを使用する別のトランザクションが終了した後にデータにアクセスできます。

さらに、トランザクションがデータを変更するときに、他のプロセスが同時に同じデータを使用している場合、トランザクションが正常にコミットされるまでデータの変更は有効になりません。張三と李斯の間の転送と、王武と趙爾の間の転送は常に互いに独立しています。

4. 耐久性

トランザクションの耐久性とは、システムに障害が発生したかどうかに関係なく、トランザクション処理の結果が永続的であることを意味します。

トランザクションが正常に完了すると、システムに障害が発生した場合でも、トランザクションによってデータベースに加えられた変更は永続的に残ります。つまり、トランザクションがコミットされると、トランザクションによってデータに加えられた変更はデータベースに永続的に保持されます。

トランザクションの ACID 原則により、トランザクションが正常にコミットされるか失敗してロールバックされるか、あるいはその 2 つのいずれかが保証されます。したがって、トランザクションに対する変更は回復可能です。つまり、トランザクションが失敗すると、そのデータ変更はトランザクションが実行される前の状態に復元されます。

MySQL トランザクションの実行構文とプロセス

MySQL は、トランザクションをサポートするために複数のストレージ エンジンを提供します。トランザクションをサポートするストレージ エンジンには、InnoDB と BDB が含まれます。InnoDB ストレージ エンジンのトランザクションは主に UNDO ログと REDO ログを通じて実装されます。MyISAM ストレージ エンジンはトランザクションをサポートしません。

拡張: どのような種類のデータベースにも、データベースの実行ステータス、日々の操作、エラー メッセージなどを記録するさまざまなログがあり、MySQL も例外ではありません。たとえば、ユーザー root が MySQL サーバーにログインすると、ユーザーのログイン時間や実行操作などがログ ファイルに記録されます。

MySQL サーバーを保守するには、多くの場合、MySQL データベースでログ操作を実行する必要があります。

  • UNDO ログ: トランザクションが実行される前にデータをコピーし、トランザクションで例外が発生したときにデータをロールバックするために使用されます。
  • REDO ログ: トランザクションの実行中にデータを更新するすべての操作を記録します。トランザクションがコミットされると、内容がディスクにフラッシュされます。

MySQL データベース基礎スキル完全演習icon-default.png?t=N7T8https://edu.csdn.net/course/detail/36210
デフォルト設定では、各 SQL ステートメントはトランザクションです。つまり、SQL ステートメントの実行後に自動的に送信されます。複数の操作を全体として結合するには、BEGIN または START TRANSACTION を使用してトランザクションを開始するか、現在のセッションの自動送信を無効にする必要があります。

トランザクションの自動送信の詳細については、 「 MySQL の自動トランザクション送信の設定」セクション を参照してください。

トランザクションを実行するための構文とプロセス

SQL は次のステートメントを使用してトランザクションを管理します。

1) トランザクションの開始
BEGIN;

 または

START TRANSACTION;

このステートメントは、トランザクションの開始点を明示的に示します。

2) トランザクションを送信する

MySQL は次のステートメントを使用してトランザクションをコミットします。

COMMIT;

COMMIT は、トランザクションをコミットする、つまりトランザクションのすべての操作をコミットすることを意味します。具体的には、トランザクション内のデータベースに対するすべての更新がディスク上の物理データベースに書き込まれ、トランザクションは正常に終了します。

トランザクションをコミットすると、トランザクションの開始以降に実行されたすべてのデータが変更され、データベースの永続的な部分になり、トランザクションの終了もマークされます。このコマンドを実行すると、トランザクションをロールバックすることはできません。この操作は、すべての変更をデータベースにコミットする準備ができている場合にのみ実行されます。

3) トランザクションのロールバック (元に戻す)

MySQL は、次のステートメントを使用してトランザクションをロールバックします。

ROLLBACK;

ROLLBACK は、トランザクションをキャンセルすることを意味します。つまり、トランザクションの実行中に何らかの障害が発生し、トランザクションの実行を続行できなくなります。システムは、トランザクション内のデータベースに対する完了した操作をすべて取り消し、最初の状態にロールバックします。トランザクションの。ここでの操作は、データベースの更新操作を指します。

トランザクションの実行中にエラーが発生した場合は、ROLLBACK ステートメントを使用して、トランザクションを開始点または指定されたホールド ポイントまでロールバックします。同時に、システムはトランザクションの開始点または特定の保存ポイントまでに行われたすべてのデータ変更をクリアし、トランザクションによって制御されているリソースを解放します。したがって、このステートメントはトランザクションの終了も示します。

要約する

BEGIN または START TRANSACTION ステートメントに続く SQL ステートメントによるデータベース データの更新操作は、ROLLBACK ステートメントまたは COMMIT ステートメントが検出されるまでトランザクション ログに記録されます。トランザクション内の操作が失敗し、ROLLBACK ステートメントが実行された場合、トランザクション ステートメントを開いた後に更新されたすべてのデータは、トランザクションが開始される前の状態にロールバックできます。トランザクション内のすべての操作が正しく完了し、COMMIT ステートメントを使用して更新されたデータをデータベースに送信すると、その時点のデータは新しい整合性のある状態になります。

デモンストレーション例

以下に、MySQL トランザクションの具体的な使用法を示す 2 つの例を示します。

例1

以下は、Zhang San のアカウントが 500 元減少したが、Li Si のアカウントが 500 元増加しなかった後に、他のセッションがデータ テーブルにアクセスするシナリオをシミュレートします。コードは 2 つのウィンドウで実行する必要があるため、ここでは読みやすいように、それらを A ウィンドウと B ウィンドウと呼びます。

1) ウィンドウ A でトランザクションを開き、mybank データベースのバンク テーブルのデータを更新します。SQL ステートメントと実行結果は次のとおりです。

mysql> USE mybank;
Database changed
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE bank SET currentMoney = currentMoney-500
    -> WHERE customerName='张三';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

2) ウィンドウ B の銀行データ テーブルのデータをクエリします。SQL ステートメントと実行結果は次のとおりです。

mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三         |      1000.00 |
| 李四         |         1.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

この結果を見ると、ウィンドウ A のトランザクションによってバンク テーブルのデータが変更されましたが、すぐにデータが更新されるわけではなく、この時点では他のセッションが更新前のデータを読み取っていることがわかります。

3) 引き続きウィンドウ A でトランザクションを実行し、トランザクションを送信します。SQL ステートメントと実行結果は次のとおりです。

mysql> UPDATE bank SET currentMoney = currentMoney+500
    -> WHERE customerName='李四';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> COMMIT;
Query OK, 0 rows affected (0.07 sec)

4) ウィンドウ B で銀行データ テーブルのデータを再度クエリします。 SQL ステートメントと実行結果は次のとおりです。

mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三         |       500.00 |
| 李四         |       501.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

COMMIT を実行してウィンドウ A でトランザクションをコミットすると、データの更新がまとめて送信され、他のセッションが更新されたデータを読み取ります。この結果から、Zhang San と Li Si の合計口座残高は移転前と一致していることがわかり、データはある整合性状態から別の整合性状態に更新されます。

前述したように、トランザクション実行中に問題が発生した場合、つまりトランザクションが正常に実行できない場合、ROLLBACK 文を使用してロールバックし、データを使用して初期状態に戻すことができます。

例 1 では、Zhang San の口座残高が 500 元に減りましたが、さらに 1,000 元を送金すると残高がマイナスになるため、元の状態に戻す必要があります。例 2 に示すように。

例 2

Zhang San のアカウント残高を 1,000 元減らし、トランザクションをロールバックします。SQL ステートメントと実行結果は次のとおりです。

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
 
mysql> UPDATE bank SET currentMoney = currentMoney-1000 WHERE customerName='张三';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql> ROLLBACK;
Query OK, 0 rows affected (0.07 sec)
 
mysql> SELECT * FROM mybank.bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 张三         |       500.00 |
| 李四         |       501.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

この結果から、トランザクションのロールバックを実行すると、アカウントデータが初期状態、つまりトランザクション実行前の状態に戻っていることがわかります。

拡大する

データベース操作では、同時に読み取られるデータの正確性を効果的に保証するために、トランザクションの分離レベルが提案されています。例 1 と例 2 のデモでは、トランザクションの分離レベルはデフォルトの分離レベルです。 MySQL では、トランザクションのデフォルトの分離レベルは REPEATABLE-READ (再読み取り可能) 分離レベルです。つまり、トランザクションが終了していない (COMMIT または ROLLBACK が実行されていない) 場合、他のセッションはコミットされていないデータのみを読み取ることができます。詳細については、「MySQL トランザクション分離レベル」

をクリックしてください。

予防

MySQL トランザクションは非常にリソースを消費する機能であるため、使用する場合は以下の点に注意してください。

1) トランザクションをできるだけ短くする

トランザクションの開始から終了まで、トランザクションの原子性、一貫性、分離性、耐久性を確保するために、データベース管理システムに大量のリソースが予約されます。マルチユーザー システムでは、大規模なトランザクションが大量のシステム リソースを占有し、システムに負荷がかかり、ソフトウェアの実行パフォーマンスに影響を与え、さらにはシステムのクラッシュを引き起こす可能性があります。

2) トランザクションでアクセスされるデータの量は最小限に抑える必要があります。

トランザクションが同時に実行される場合、トランザクションで操作されるデータの量が少なくなるほど、トランザクション間で同じデータに対する操作が少なくなります。

3) データをクエリするときはトランザクションを使用しないようにしてください

データの参照やクエリを行ってもデータベース内のデータは更新されないため、過剰なシステム リソースの占有を避けるために、データのクエリにトランザクションを使用しないようにする必要があります。

4) トランザクション処理中にユーザー入力を待たないようにしてください。

トランザクション処理中にユーザーのデータ入力を待つ必要がある場合、トランザクションが長時間リソースを占有することになり、システムの輻輳が発生する可能性があります。

大昌上級データベースエンジニアmysqlデータベース実習icon-default.png?t=N7T8https://edu.csdn.net/course/detail/39021 

おすすめ

転載: blog.csdn.net/m0_37449634/article/details/135554108