I upgraded a legacy project from:
PHP 5.6 -> 8.0
doctrine/orm 2.5.14 -> 2.13.4
doctrine/data-fixtures 1.2.2 -> 1.5.3
Now the following code throws the exception:
PDOException : There is no active transaction /var/www/html/src/vendor/doctrine/dbal/src/Driver/PDO/Connection.php:120 /var/www/html/src/vendor/doctrine/dbal/src/Connection.php:1481 /var/www/html/src/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:280
use DoctrineCommonDataFixturesLoader; use DoctrineCommonDataFixturesPurgerORMPurger; use DoctrineCommonDataFixturesExecutorORMExecutor; $ormPurger = new ORMPurger($entityManager, $exclude); $ormPurger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE); $executor = new ORMExecutor($entityManager, $ormPurger); $executor->execute($loader->getFixtures());
The exception is thrown when DoctrineORMEntityManager::transactional calls:
$this->conn->commit()
In the documentation I read:
Not all RDBMS have the capability to allow TRUNCATE statements inside transactions though. Notably, MySQL will produce the infamous There is no active transaction message when we attempt to close a transaction that was already implicitly closed.
doctrine-data-fixtures/en/latest/explanation/transactions-and-purging.html
— UPDATE
I was able to fix the error by using the default purge mode PURGE_MODE_DELETE instead of PURGE_MODE_TRUNCATE. So does that mean I can’t use TRUNCATE operations when using ORMExecutor::execute?
Advertisement
Answer
RDBMS such as MySQL does not allow TRUNCATE statements inside transactions.
ORMExecutor::execute(array $fixtures, $append = false) perform SQL operations in a transaction. So we have to perform any TRUNCATE operations outside this transaction.
$purger = new ORMPurger($em, $exclude); $purger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE); $purger->purge(); $executor = new ORMExecutor($em); $executor->execute($loader->getFixtures(), append: true);
To use executor without purging we can pass true to the 2nd argument of execute.
// Don't do this unless you want to purge all the tables // in the database prior to appending fixtures $executor->execute($loader->getFixtures(), new ORMPurger());