How to fix the «DDL statements are not allowed in transactions» failure with the addCommitCallback()

Why do you got the failure?

The cause of the message is an attempt to execute a DDL statement inside a transaction.

By default, PDO allows to execute the DDL statements inside a transaction:

Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.

http://php.net/manual/en/pdo.begintransaction.php

So, it is allowed in PDO, but it breaks the possibility to rollback the transaction.
For this reason, Magento 2 denies to execute the DDL statement inside a transaction:




How to fix it

Method 1: \Magento\Framework\Model\ResourceModel\AbstractResource::addCommitCallback()

Use the \Magento\Framework\Model\ResourceModel\AbstractResource::addCommitCallback() method to run your DDL statements after the transaction has been committed:




Examples from the core









Method 2: \Magento\Framework\Model\AbstractModel::afterCommitCallback()

Override the \Magento\Framework\Model\AbstractModel::afterCommitCallback() method in your model to run your DDL statements after the transaction has been committed:

The core never uses this possibility, but it does work.

Method 3: model_save_commit_after and <prefix>_save_commit_after

Subscribe to the model_save_commit_after or the <prefix>_save_commit_after event:

Examples from the core






See also: