English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

MySQLトランザクション

MySQLのトランザクションは、操作量が大きく、複雑なデータの処理に主に使用されます。例えば、人員管理システムで、ある人員を削除する場合、その人員の基本情報を削除するだけでなく、その人員に関連する情報(例:メールボックス、記事など)も削除する必要があります。このように、これらのデータベース操作文はトランザクションとして構成されます!

  • MySQLでは、Innodbデータベースエンジンを使用しているデータベースやテーブルのみがトランザクションをサポートしています。

  • トランザクション処理は、データベースの整合性を維持し、一括のSQL文が完全に実行されるか、または全く実行されないことを保証するために使用されます。

  • トランザクションはinsert、update、delete文の管理に使用されます

一般的に、トランザクションは満たす必要がある4個条件(ACID)::原子性(A原子性(tomicity)、一貫性(C一貫性(onsistency)、孤立性(I孤立性(solation)、持久性(D持久性(urability)。

  • 原子性:一つのトランザクション(transaction)のすべての操作は、完全に完了するか、または全く完了しない、中間のどこかで終了することはありません。トランザクションの実行中にエラーが発生すると、トランザクションが開始前の状態にロールバック(Rollback)されるため、このトランザクションが実際に実行されたかのような感じです。

  • 一貫性:トランザクションの開始前と終了後、データベースの整合性は破壊されていません。これは、書き込まれたデータがすべての設定ルールに完全に一致していることを意味し、データの正確性、連続性、および後続のデータベースが自動的に予定された作業を完了できることを含みます。

  • 隔離性:データベースは同時に読み書きおよび変更を並行して実行する複数の並行トランザクションに対してデータに対して読み書きおよび変更を行う能力を持ちます、隔離性は複数のトランザクションが並行して実行される際に交叉実行によってデータの不一致を防ぐことができます。トランザクション隔離は異なるレベルに分けられます、読み未提交(Read uncommitted)、読みコミット(read committed)、可重复読み(repeatable read)、並行化(Serializable)を含みます。

  • 持久性:トランザクション処理が終了すると、データの変更は永続的になります、システム障害が発生しても失われることはありません。

MySQLのコマンドラインのデフォルト設定では、トランザクションは自動的にコミットされます、つまりSQL文を実行するとすぐにCOMMIT操作が実行されます。したがって、明示的にトランザクションを開始するには、コマンドBEGINまたはSTART TRANSACTIONを使用するか、コマンドSET AUTOCOMMIT=0を実行して現在のセッションの自動コミットを禁止する必要があります。

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

  • BEGINまたはSTART TRANSACTIONを使用して明示的にトランザクションを開始します;

  • COMMITはCOMMIT WORKも使用できますが、両者は等価です。COMMITはトランザクションをコミットし、データベースに対して行ったすべての変更を永続化します;

  • ROLLBACKはROLLBACK WORKも使用できますが、両者は等価です。ロールバックはユーザーのトランザクションを終了し、未提交のすべての変更を取り消します;

  • SAVEPOINT identifier、SAVEPOINTはトランザクション中に保存点を作成することを許可します、一つのトランザクションには複数のSAVEPOINTが存在できます;

  • RELEASE SAVEPOINT identifierを使用してトランザクションの保存点を削除します、指定された保存点がない場合、このステートメントを実行すると例外が発生します;

  • ROLLBACK TO identifierを使用してトランザクションをマークポイントに戻します;

  • SET TRANSACTIONはトランザクションの隔離レベルを設定します。InnoDBストレージエンジンはREAD UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLEなどのトランザクションの隔離レベルを提供します。

MYSQLのトランザクション処理には主に2つの方法があります:

1BEGIN、ROLLBACK、COMMITを使用して実現

  • BEGIN トランザクションを開始

  • ROLLBACK トランザクションロールバック

  • COMMIT  トランザクション確認

2、直接 SET を使って MySQL の自動コミットモードを変更します:

  • SET AUTOCOMMIT=0   自動コミットを禁止

  • SET AUTOCOMMIT=1 自動コミットを開始

mysql> use w3codebox;
Database changed
mysql> CREATE TABLE w3codebox_transaction_test(id int(5)) engine=innodb; # データテーブルを作成
Query OK, 0 rows affected (0.04 sec)
 
mysql> select * from w3codebox_transaction_test;
Empty set (0.01 sec)
 
mysql> begin; # トランザクションを開始
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into w3codebox_transaction_test value(5);
Query OK, 1 rows affected (0.01 sec)
 
mysql> insert into w3codebox_transaction_test value(6);
Query OK, 1 rows affected (0.00 sec)
 
mysql> commit; # トランザクションをコミット
Query OK, 0 rows affected (0.01 sec)
 
mysql> select * from w3codebox_transaction_test;
+------+
| id |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql> begin; # トランザクションを開始
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into w3codebox_transaction_test values(7);
Query OK, 1 rows affected (0.00 sec)
 
mysql> rollback; # ロールバック
Query OK, 0 rows affected (0.00 sec)
 
mysql> select * from w3codebox_transaction_test; # ロールバックによりデータが挿入されていない
+------+
| id |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql>

PHPでのトランザクションの例

<?php
$dbhost = 'localhost';  // MySQLサーバーホストアドレス
$dbuser = 'root';            // MySQLユーザー名
$dbpass = '';123456';          // MySQLユーザー名パスワード
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(!$conn)
{
    die('接続失敗: ' . mysqli_error($conn));
}
// エンコーディングを設定し、中国語のゴシップを防ぐ
mysqli_query($conn, "set names utf8);
mysqli_select_db($conn, 'w3codebox');
mysqli_query($conn, "SET AUTOCOMMIT=0"); // 自動コミットを設定しない、なぜならMYSQLはデフォルトで即座に実行されるからです
mysqli_begin_transaction($conn);            // トランザクションの開始定義
 
if(!mysqli_query($conn, "insert into w3codebox_transaction_test(id)values(8)")
{
    mysqli_query($conn, "ROLLBACK");     // 実行失敗時のロールバック判定
}
 
if(!mysqli_query($conn, "insert into w3codebox_transaction_test(id)values(9)")
{
    mysqli_query($conn, "ROLLBACK");      // 実行失敗時のロールバック判定
}
mysqli_commit($conn);            //トランザクションの実行
mysqli_close($conn);
?>