doctrine / DoctrineFixturesBundle

Symfony integration for the doctrine/data-fixtures library
MIT License
2.44k stars 202 forks source link

"No active transaction" exception with PHP 8.0 #348

Closed PapyDanone closed 3 years ago

PapyDanone commented 3 years ago

Most likely related to https://github.com/doctrine/migrations/issues/1104 and https://github.com/doctrine/migrations/issues/1139

Versions installed:

doctrine/data-fixtures               1.5.0           
doctrine/dbal                        2.13.0             
doctrine/doctrine-bundle             2.3.1           
doctrine/doctrine-fixtures-bundle    3.4.0              
doctrine/doctrine-migrations-bundle  2.2.2              
doctrine/migrations                  2.3.x-dev 5c7b119  
doctrine/orm                         2.8.4

To reproduce:

bin/console doctrine:fixtures:load --verbose

purging database loading App\DataFixtures\LoadUserData [...] In Connection.php line 1845:
[PDOException]
There is no active transaction

Stack trace:

Exception trace:
  at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:1845
 PDO->rollBack() at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:1845
 Doctrine\DBAL\Connection->rollBack() at /vagrant/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:253
 Doctrine\ORM\EntityManager->transactional() at /vagrant/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php:73
 Doctrine\Common\DataFixtures\Executor\ORMExecutor->execute() at /vagrant/vendor/doctrine/doctrine-fixtures-bundle/Command/LoadDataFixturesDoctrineCommand.php:155
 Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand->execute() at /vagrant/vendor/symfony/console/Command/Command.php:256
 Symfony\Component\Console\Command\Command->run() at /vagrant/vendor/symfony/console/Application.php:989
 Symfony\Component\Console\Application->doRunCommand() at /vagrant/vendor/symfony/framework-bundle/Console/Application.php:96
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /vagrant/vendor/symfony/console/Application.php:290
 Symfony\Component\Console\Application->doRun() at /vagrant/vendor/symfony/framework-bundle/Console/Application.php:82
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /vagrant/vendor/symfony/console/Application.php:166
 Symfony\Component\Console\Application->run() at /vagrant/bin/console:42

Possible resolution:

I haven't had the time too look into this in details but since this happens in a Rollback, the solution may be similar to https://github.com/doctrine/migrations/pull/1143

Thank you for the help, and please let me know how I can help further.

PapyDanone commented 3 years ago

Actually using TransactionHelper in Doctrine\ORM\EntityManager fixes the issue:

line 237:

    public function transactional($func)
    {
        if (! is_callable($func)) {
            throw new InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"');
        }

        $this->conn->beginTransaction();

        try {
            $return = call_user_func($func, $this);

            $this->flush();
//            $this->conn->commit();
            TransactionHelper::commitIfInTransaction($this->conn);

            return $return ?: true;
        } catch (Throwable $e) {
            $this->close();
//            $this->conn->rollBack();
            TransactionHelper::rollbackIfInTransaction($this->conn);

            throw $e;
        }
    }
greg0ire commented 3 years ago

Do you know if any DDL statements are executed before the attempt to commit? The issues you are linking to should only arise when combining PHP 8 + PDO + MySQL or Oracle + DDL statements.

Maybe that's because of the "purging database" step? Does it maybe work with DROP + CREATE TABLE?

PapyDanone commented 3 years ago

@greg0ire thanks for putting me on the right track. One of the fixture files contained an ALTER TABLE statement which caused the issue.