引き続きMySQLのトランザクション管理を見ていきましょう。次はトランザクションを rollback するケースを確認します。

(補足)テーブルの確認

これから categories テーブルを使ってトランザクションの仕組みについて確認します。事前に以下のとおり、レコードが出力されることを確認しておいてください。

MariaDB [eldb]> select * from categories;
+----+-------------+
| id | title       |
+----+-------------+
|  1 | Programming |
|  2 | Design      |
|  3 | Marketing   |
+----+-------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

もしデータが異なる場合は、以下のSQLを実行して categories テーブルのレコードを再登録しておいてください。

delete from categories;
insert into categories (id, title) values (1, 'Programming');
insert into categories (id, title) values (2, 'Design');
insert into categories (id, title) values (3, 'Marketing');

1つ前の commit を行った場合は、上記のSQLを実行してデータを再登録しておいてください。

トランザクションの使用例 - rollback する場合

前回と同じように2つのMySQLクライアントプログラムを起動してトランザクション管理を行う様子を見ていきましょう。Aさん、Bさんの2人がMySQLを操作する様子を想定して、以下のシナリオに沿ってMySQLを操作します。

作業No Aさんの操作 Bさんの操作
1 begin;
2 insert into categories values(4, 'Piano');
3 insert into categories values(5, 'Guitar');
4 select * from categories;
※Aさんにはコミットされていない結果が表示される
5 select * from categories;
※Bさんにはコミットされていない結果は表示されない
6 rollback;
7 select * from categories;
※Aさんにはロールバックされた結果が表示される
8 select * from categories;
※Bさんにもロールバック結果(変化なし)が表示される

作業No.6 以降が前回と異なります。作業No.1 〜 No.5までは前回と同じです。

まずはAさん、Bさんを想定して2つのMySQLクライアントプログラムを起動します。

両方のMySQLクライアントプログラムに root ユーザでログインします。また use eldb として eldb データベースに接続しておきます。

作業No.1 の手順にしたがってAさんのMySQLクライアントプログラム上で begin コマンドを入力します。

MariaDB [eldb]> begin;                                     
Query OK, 0 rows affected (0.00 sec)

MariaDB [eldb]> 

Query OK と表示されればSQLは正しく処理できています。ここで begin 命令が成功したので、AさんのMySQLクライアントプログラムがトランザクションを開始した状態になっています。begin 命令でトランザクションを開始すると、以降に実行するSQLは commit 命令を実行されるまでデータベースには反映されません。

次に作業No.2、3 の手順にしたがってAさんのMySQLクライアントプログラム上で insert 文を2件入力します。

MariaDB [eldb]> insert into categories values(4, 'Piano');
Query OK, 1 row affected (0.00 sec)

MariaDB [eldb]> insert into categories values(5, 'Guitar');
Query OK, 1 row affected (0.00 sec)

MariaDB [eldb]> 

Query OK と表示されればSQLは正しく処理できています。ここでAさんのトランザクション上で2件の新規レコードが追加されたことになります。

次に作業No.4 の手順にしたがって、AさんのMySQLクライアントプログラム上で select 文を入力してみましょう。

MariaDB [eldb]> select * from categories;
+----+-------------+
| id | title       |
+----+-------------+
|  1 | Programming |
|  2 | Design      |
|  3 | Marketing   |
|  4 | Piano       |
|  5 | Guitar      |
+----+-------------+
5 rows in set (0.00 sec)

MariaDB [eldb]> 

上記の実行結果のように、さきほど insert 文で追加した id45 のレコードを確認できます。現時点ではトランザクションをコミットしていませんが、トランザクションを開始したAさんは最新の結果を確認できます。

次に作業No.5 の手順にしたがって、BさんのMySQLクライアントプログラムから同様の select 文を実行します。

MariaDB [eldb]> select * from categories;
+----+-------------+
| id | title       |
+----+-------------+
|  1 | Programming |
|  2 | Design      |
|  3 | Marketing   |
+----+-------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

そうするとAさんの結果とは異なり、categories テーブルのレコードは3件しか表示されていないことがわかります。これはAさん実行したSQL(No.3, 4 の insert 文)はトランザクション管理下にあり、まだコミットされていないためです。

次に作業No.6 の手順にしたがって、AさんのMySQLクライアントプログラムから rollback 命令を実行します。

MariaDB [eldb]> rollback;
Query OK, 0 rows affected (0.01 sec)

MariaDB [eldb]> 

Query OK と表示されればSQLは正しく処理できています。ここでAさんのトランザクションはロールバックされたので、追加した2件のレコードは取り消されます。

次に作業No.7 の手順にしたがって、AさんのMySQLクライアントプログラムから select 文を実行します。

MariaDB [eldb]> select * from categories;
+----+-------------+
| id | title       |
+----+-------------+
|  1 | Programming |
|  2 | Design      |
|  3 | Marketing   |
+----+-------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

実行結果を見ると、さきほど登録した2件のレコードが取り消されているのがわかります。このようにトランザクションロールバックすれば、トランザクション内で実行したSQLをキャンセルできます。

さいごに作業No.8 の手順にしたがって、BさんのMySQLクライアントプログラムから前回と同じ select 文を実行してみましょう。

MariaDB [eldb]> select * from categories;
+----+-------------+
| id | title       |
+----+-------------+
|  1 | Programming |
|  2 | Design      |
|  3 | Marketing   |
+----+-------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

そうするとトランザクションがロールバックされたので、Bさんの画面には以前と変わらない結果(3件のレコード)が出力されているのがわかります。


(参考)オートコミットモード

多くのデータベースプロダクトにおいては、デフォルトでオートコミット(自動コミット)が有効になっています。これは一つのSQLが発行されるごとに自動的にコミットされる仕組みです。 begin 命令を呼び出すことは "一時的にオートコミットを無効にすること" と考えることもできます。