🎻

[Symfony] Doctrine migrationsのall_or_nothingはMySQLでは効きません

2020/06/04に公開

↓これの話です。

https://twitter.com/ttskch/status/1265818223921868800

Doctrine migrationsの all_or_nothing オプション

Doctrine migrationsには all_or_nothing というオプションがあります。

これを有効にしておけば、マイグレーションスクリプト全体がトランザクション内で実行され、途中でエラーが発生したらすべてがロールバックされるという安心オプションです。

が、 データベースにMySQLを使っている場合はこのオプションは使えません 😱

MySQLはトランザクション内でのDDLの実行をサポートしていない

Doctrine migrationsのドキュメントを見ると、以下のように書かれています。

This is only works if your database supports transactions for DDL statements.

https://www.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/configuration.html#all-or-nothing-transaction

DDLステートメントのトランザクションがサポートされているデータベースでしか動作しませんよ、とのこと。

DDLステートメントの DDL とは Data Definition Language(データ定義言語) の略で、データベースやテーブルなどのデータベースオブジェクトを定義・変更するステートメントのことです。

MySQLにおけるDDLステートメントの一覧は下記。(DBスキーマのマイグレーションでよく使う CREATE TABLE DROP TABLE ALTER TABLE とかですね)

そして、以下のページにも明記されているとおり、MySQLではトランザクション内でのDDLの実行はサポートされていません。

どのデータベースなら対応しているのか

こちらの比較表 によると

DB DDLのトランザクション
Oracle -
Postgres
SQL Server
IBM DB2
MySQL -
MariaDB -
Firebird
H2 -
HSQLDB -
Derby -
SQLite

という感じみたいです。

GitHubで編集を提案

Discussion