無料Wikiサービス | デモページ
Linuxなどのメモ書き
検索

Adsense

MySQL トランザクション の差分
Rev.8→Rev.9  追加箇所 削除箇所


トランザクションを使うと複数のクエリをまとめて1つの処理として扱うことができる。処理の途中でエラーになって処理を取り消したいような場合はROLLBACKをすることで変更内容を元に戻すことができる。

トランザクションはInnoDBテーブルを使用する(デフォルトのMyISAMではトランザクションを使用できない)。

InnoDBテーブルの作成

新規に作るテーブルをInnoDBにするには、以下のようにする。

mysql> CREATE TABLE friends (id SERIAL, name VARCHAR(30)
NOT NULL, address VARCHAR(100), birthday DATETIME) TYPE=InnoDB;

既存のテーブルのInnoDBに変更する場合は以下のとおり。

mysql> ALTER TABLE friends TYPE = INNODB;

トランザクションの開始と完了およびROLLBACK

mysql> START TRANSACTION;トランザクション開始するこれ以降入力されたSQLクエリトランザクションとしてわれるトランザクションった場合COMMIT(DB結果反映)ROLLBACK(トランザクション開始前状態)をする
mysql> COMMIT;
mysql> ROLLBACK;


mysql> START TRANSACTION;

START TRANSACTION以降のクエリをDBに反映させてトランザクションを完了する場合は以下のようにする。

mysql> COMMIT;

途中でエラーが発生する等してSTART TRANSACTION以降のクエリを取り消したい場合はROLLBACKする。

mysql> ROLLBACK;

実際にやってみた時の挙動

実際にトランザクションを使ってみた時の挙動を以下にまとめる。

通常のトランザクション処理の動作を表1に示す。

  • No.2でトランザクションを開始する
  • No.3でテーブルにレコードを追加する
  • No.4でレコードを表示させると、スレッドBからは追加されたレコードがまだ見えない。これはトランザクションがまだ完了していないため。
  • No.5でトランザクションを完了させるとDBに反映されてスレッドBからも見えるようになる。

表1 トランザクションの挙動(COMMITする場合)

No.
スレッドA
スレッドB
1
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
2
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

3
mysql> INSERT INTO friends
(name, address, birthday)
VALUES("suzuki", "Kamata xxxx",
"2006-05-13 12:34:56");
Query OK, 1 row affected (0.00 sec)

4
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
5
mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)

6
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)


トランザクションROLLBACKする挙動1 トランザクション使った挙動2

No.
スレッドA
スレッドB
1
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
2
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

3
mysql> INSERT INTO friends
(name, address, birthday)
VALUES("suzuki", "Kamata xxxx",
"2006-05-13 12:34:56");
Query OK, 1 row affected (0.00 sec)

4
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
+----+--------+
1 row in set (0.00 sec)
5
mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)

6
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
  • No.2でトランザクションを開始する
  • No.3でレコードを追加する。
  • No.5でROLLBACKするとトランザクション内のクエリ(No.3)が取り消されているのがNo.6で確認できる。

表2 トランザクションの挙動(ROLLBACKする場合)

No.
スレッドA
スレッドB
1
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

2
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

3
mysql> INSERT INTO friends
(name, address, birthday)
VALUES("tanaka", "Kamata xxxx",
"2006-05-13 12:34:56");
Query OK, 1 row affected (0.00 sec)

4
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
| 3 | tanaka |
+----+--------+
3 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
5
mysql> ROLLBACK;

6
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

表2 ROLLBACKの挙動

No.
スレッドA
スレッドB
1
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)

2
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

3
mysql> INSERT INTO friends
(name, address, birthday)
VALUES("tanaka", "Kamata xxxx",
"2006-05-13 12:34:56");
Query OK, 1 row affected (0.00 sec)

4
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
| 3 | tanaka |
+----+--------+
3 rows in set (0.00 sec)

mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
5
mysql> ROLLBACK;

6
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)
mysql> select id,name from friends;
+----+--------+
| id | name |
+----+--------+
| 1 | tomita |
| 2 | suzuki |
+----+--------+
2 rows in set (0.00 sec)