ビューの変更はトランザクションセーフではない。
出典: MySQL Practice Wiki
説明
MySQLにおいてはトランザクションはストレージエンジンの階層で処理される。そしてビューはストレージエンジンの上位層で処理される。(実際にはベースとなっているテーブルへのマッピングをするだけである。)したがって、ビューの変更はトランザクションセーフではない。ビューを使ったトランザクションを実装する場合には注意が必要である。
動作例
例えば次のようなテーブルとビューを考える。
mysql> CREATE TABLE t1 (a BIGINT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=InnoDB; mysql> CREATE TABLE t2 LIKE t1; mysql> CREATE VIEW v1 AS SELECT a FROM t1;
そしてトランザクションを開始する。
mysql> START TRANSACTION; mysql> INSERT INTO v1 VALUES(1),(2),(3);
他のセッションからビューの定義を変更する。(参照するテーブルをt1からt2に変更。)
mysql> CREATE OR REPLACE VIEW v1 AS SELECT a FROM t2;
トランザクションを継続。
mysql> INSERT INTO v1 VALUES(4),(5),(6); mysql> COMMIT;
そうすると以下のような結果になる。
mysql> SELECT * FROM t1; +---+ | a | +---+ | 1 | | 2 | | 3 | +---+ 3 rows in set (0.00 sec) mysql> SELECT * FROM t2; +---+ | a | +---+ | 4 | | 5 | | 6 | +---+ 3 rows in set (0.00 sec)
対処
このような結果は望ましいものではない場合が多い。このような結果を回避するためには、ストレージエンジンの上位層での処理が必要となる。つまり、LOCK TABLESをするべきなのである。
mysql> LOCK TABLES t1 WRITE, t2 WRITE; mysql> CREATE OR REPLACE VIEW v1 AS SELECT a FROM t2; mysql> UNLOCK TABLES;

