diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php index 30f977a2d8..c588dc9dfa 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php @@ -11,7 +11,6 @@ use Drupal\Core\Database\DatabaseException; use Drupal\Core\Database\Connection as DatabaseConnection; use Drupal\Component\Utility\Unicode; -use Drupal\Core\Database\TransactionNoActiveException; /** * @addtogroup database @@ -428,13 +427,16 @@ public function rollBack($savepoint_name = 'drupal_transaction') { catch (\PdoException $e) { } - // Convert the \PdoException to a Drupal database exception. if ($e->getMessage() === 'There is no active transaction') { - // Note that on PHP 7 this code is never called as an exception is not - // thrown by PDO in this case. - throw new TransactionNoActiveException($e->getMessage(), $e->getCode(), $e); + // On PHP 7 $this->connection->rollback() does not throw an exception if + // there is no active transaction. In order to maintain consistent + // behaviour on PHP 8 we have to ignore this error. This situation occurs + // when tables are altered or created (DDL transactions are not + // supported). + trigger_error('Rollback attempted when there is no active transaction. This can cause data integrity issues.', E_USER_WARNING); + return; } - throw new DatabaseExceptionWrapper($e->getMessage(), $e->getCode(), $e); + throw $e; } /** @@ -449,7 +451,7 @@ protected function doCommit() { throw new DatabaseExceptionWrapper($e->getMessage(), $e->getCode(), $e); } // On PHP 7 $this->connection->commit() does not throw an exception if - // there is no active transaction.In order to maintain consistent + // there is no active transaction. In order to maintain consistent // behaviour on PHP 8 we have to assume that all queries have been // committed. This situation occurs when tables are altered or created // (DDL transactions are not supported). diff --git a/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php b/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php index 7831307af2..dc55027339 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php @@ -259,19 +259,16 @@ public function testTransactionWithDdlStatement() { $this->insertRow('row'); $this->executeDDLStatement(); - // Rollback the outer transaction. - try { - $transaction->rollBack(); - unset($transaction); - // The PHP 7 MySQL driver does not trigger an exception when calling - // rollback and there is no active transaction. - if (PHP_VERSION_ID >= 80000) { - $this->fail('Rolling back a transaction containing DDL should fail.'); - } - } - catch (TransactionNoActiveException $e) { - // Expected exception; just continue testing. + // The PHP 7 MySQL driver does not trigger an exception when calling + // rollback and there is no active transaction. + if (PHP_VERSION_ID >= 80000) { + $this->expectWarning(); + $this->expectWarningMessage('Rollback attempted when there is no active transaction. This can cause data integrity issues.'); } + + // Rollback the outer transaction. + $transaction->rollBack(); + unset($transaction); $this->assertRowPresent('row'); } }