You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This appears to be an issue in PHP 8.0, with a database like MySQL/MariaDB that has implicit commits.
We're currently in the process of upgrading from PHP 7.4 to 8.0 (then to other 8.x versions, 8.0 is an intermediate update)
Our build process for our test environments involves running doctrine:build --all, which as part of its execution calls sfDoctrineInsertSqlTask. This task ends up calling \Doctrine_Export::exportClasses. This method generates a bunch of DDL commands and runs them inside a transaction, finally calling commit.
In PHP 7.4, this ran into no issues.
In PHP 8.0, we are getting a PDOException with the text "There is no active transaction".
It looks like the root cause of this is the PDO classes internal transaction state tracking becoming out of sync with the database when the database implicitly commits. In 7.4 this used to just be silent and the commit call would essentially be a no-op. In 8.0 the internal transaction state tracking of PDO was updated to begin throwing this exception when it recognized the actual connection was no longer in a transaction.
Here is a related issue with its fix in the modern doctrine/migrations library: doctrine/migrations#1104. For that issue they updated their migration-related commit calls to first check if they were still in an active transaction (and have isTransactional for a more permanent fix).
Given the behavior of exportClasses to almost always contain DDL queries, I think it likely makes sense to check if we're still in a transaction before calling commit. This behavior could also be an override of the exportClasses method in \Doctrine_Export_Mysql. Interested in hearing other thoughts on this or if there's something I missed.
The text was updated successfully, but these errors were encountered:
Thanks for the detailed description.
It took me a while to find, this is the PR for issue #1104: doctrine/migrations#1131
The TransactionHelper in that PR seems to me to be an reasonable fix. If the connections is PDO and we are inTransaction then commit.
This appears to be an issue in PHP 8.0, with a database like MySQL/MariaDB that has implicit commits.
We're currently in the process of upgrading from PHP 7.4 to 8.0 (then to other 8.x versions, 8.0 is an intermediate update)
Our build process for our test environments involves running
doctrine:build --all
, which as part of its execution callssfDoctrineInsertSqlTask
. This task ends up calling\Doctrine_Export::exportClasses
. This method generates a bunch of DDL commands and runs them inside a transaction, finally calling commit.In PHP 7.4, this ran into no issues.
In PHP 8.0, we are getting a PDOException with the text "There is no active transaction".
It looks like the root cause of this is the PDO classes internal transaction state tracking becoming out of sync with the database when the database implicitly commits. In 7.4 this used to just be silent and the commit call would essentially be a no-op. In 8.0 the internal transaction state tracking of PDO was updated to begin throwing this exception when it recognized the actual connection was no longer in a transaction.
Here is a related issue with its fix in the modern doctrine/migrations library: doctrine/migrations#1104. For that issue they updated their migration-related commit calls to first check if they were still in an active transaction (and have isTransactional for a more permanent fix).
Given the behavior of
exportClasses
to almost always contain DDL queries, I think it likely makes sense to check if we're still in a transaction before calling commit. This behavior could also be an override of theexportClasses
method in\Doctrine_Export_Mysql
. Interested in hearing other thoughts on this or if there's something I missed.The text was updated successfully, but these errors were encountered: