🎻
[Symfony] Doctrine migrationsのall_or_nothingはMySQLでは効きません
↓これの話です。
Doctrine migrationsの all_or_nothing オプション
Doctrine migrationsには all_or_nothing というオプションがあります。
- https://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html
- https://www.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/configuration.html#all-or-nothing-transaction
これを有効にしておけば、マイグレーションスクリプト全体がトランザクション内で実行され、途中でエラーが発生したらすべてがロールバックされるという安心オプションです。
が、 データベースにMySQLを使っている場合はこのオプションは使えません 😱
MySQLはトランザクション内でのDDLの実行をサポートしていない
Doctrine migrationsのドキュメントを見ると、以下のように書かれています。
This is only works if your database supports transactions for DDL statements.
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 | ⭕ |
という感じみたいです。
Discussion