MySQLストアドプロシージャ内でROLLBACKトランザクションを実行する方法
はじめに
ROLLBACKは、トランザクション開始後に行われたデータベースへの変更をすべて取り消すためのコマンドです。MySQLのストアドプロシージャ内でROLLBACKを実行したい場合は、あらかじめEXITハンドラを宣言しておく必要があります。このハンドラは、sqlexception(SQL例外)またはsqlwarning(SQL警告)のどちらに対しても定義できます。
以下では、実際にROLLBACKを含むストアドプロシージャを作成し、その動作を順を追って確認していきます。
検証用テーブルの準備
まず、次のような構造を持つテーブルggを用意します。
mysql> SHOW CREATE TABLE gg\G
*************************** 1. row ***************************
Table: gg
Create Table: CREATE TABLE `gg` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(30) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)このテーブル定義から分かるように、NameカラムにはNULL値を挿入できません。また、テーブルには次のようなデータが格納されています。
mysql> SELECT * FROM gg; +----+---------+ | Id | Name | +----+---------+ | 1 | Mohan | | 2 | Gaurav | | 3 | Sohan | | 4 | Saurabh | | 5 | Yash | | 6 | Rahul | +----+---------+ 6 rows in set (0.00 sec)
ROLLBACKを行うストアドプロシージャの作成例
それでは、EXITハンドラを使ってROLLBACKを実装したストアドプロシージャを作成してみましょう。
mysql> DELIMITER //
mysql> CREATE PROCEDURE st_transaction_Rollback()
-> BEGIN
-> DECLARE exit handler FOR sqlexception
-> BEGIN
-> ROLLBACK;
-> END;
-> DECLARE exit handler FOR sqlwarning
-> BEGIN
-> ROLLBACK;
-> END;
-> START TRANSACTION;
-> INSERT INTO gg(name) VALUES();
-> UPDATE gg SET name = 'YashPal' WHERE id = 5;
-> COMMIT;
-> END //
Query OK, 0 rows affected (0.02 sec)
mysql> DELIMITER ;
mysql> CALL st_transaction_Rollback();
Query OK, 0 rows affected (0.00 sec)プロシージャのポイント
DECLARE exit handler FOR sqlexception:SQL例外が発生した時点で処理を中断し、ROLLBACKを実行します。DECLARE exit handler FOR sqlwarning:SQL警告が発生した場合も同様にROLLBACKを実行します。START TRANSACTIONでトランザクションを開始し、問題がなければ最後にCOMMITで変更を確定します。- エラーが発生した場合はCOMMITに到達せず、ハンドラによってトランザクション開始以降のすべての変更がロールバックされます。
実行結果の確認
プロシージャ実行後のテーブルの内容を見てみましょう。
mysql> SELECT * FROM gg; +----+---------+ | Id | Name | +----+---------+ | 1 | Mohan | | 2 | Gaurav | | 3 | Sohan | | 4 | Saurabh | | 5 | Yash | | 6 | Rahul | +----+---------+ 6 rows in set (0.00 sec)
上記の結果セットから、UPDATE文による変更(id=5の名前を「YashPal」へ更新)がロールバックされていることが分かります。これは、最初のINSERT文がNULL値を挿入しようとしてエラーをスローしたためです。エラー発生時にEXITハンドラが起動し、トランザクション全体がROLLBACKされたのです。
まとめ
MySQLのストアドプロシージャ内でトランザクションを安全に扱うには、EXITハンドラを宣言し、例外や警告の発生時にROLLBACKを実行するのが基本です。なお、トランザクション機能を利用するには、対象テーブルがInnoDBなどトランザクション対応のストレージエンジンである必要がある点にも注意してください。
-
MySQLのストアドプロシージャ内でSTART TRANSACTIONを実行する方法
MySQLでは、START TRANSACTIONを実行すると新しいトランザクションが開始され、自動コミット(auto-commit)モードがオフに設定されます。これにより、明示的にCOMMITまたはROLLBACKを実行するまで、データの変更内容は確定されません。以下の例では、START TRANSACTIONを含むストアドプロシージャを作成し、employee.tblテーブルに新しいレコードを挿入します。まず、対象となるテーブルには現在、次のデータが格納されています。mysql> Select * from employee.tbl; +----+---------+ | Id |
-
MySQLストアドプロシージャ内で別のストアドプロシージャを呼び出す方法
MySQLのストアドプロシージャは、その内部で別のストアドプロシージャを呼び出すことが可能です。これはCALLステートメントを使用することで実現でき、処理をモジュール化して再利用性を高める上で非常に便利な機能です。ここでは、あるストアドプロシージャが別のストアドプロシージャを呼び出し、last_insert_id()を取得する具体例を見ていきましょう。サンプルテーブルの作成まず、例として使用するテーブルを作成します。以下のテーブルは、自動採番されるIDと名前を持つ従業員テーブルです。mysql> CREATE TABLE employee.tbl(Id INT NOT NULL AUTO