diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php index da77a89c76..10f28c53e8 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php @@ -431,12 +431,16 @@ public function rollBack($savepoint_name = 'drupal_transaction') { throw new TransactionNoActiveException(); } + // MySQL will automatically commit transactions when tables are altered or + // created (DDL transactions are not supported). On PHP 7 + // $this->connection->rollback() does not throw an exception if there is no + // active transaction. This behavior is fixed in PHP 8. In order to maintain + // consistent behavior regardless of PHP version, prevent triggering an + // exception on PHP 8. This ensures that the error that has caused the + // rollback is properly reported. if (!$this->connection->inTransaction()) { - // On PHP 7 $this->connection->rollback() does not throw an exception if - // there is no active transaction. In order to maintain consistent - // behavior on PHP 8 we have to ignore this error. This situation occurs - // when tables are altered or created (DDL transactions are not - // supported). + // This code is unreachable on PHP 7 when a DDL statement has caused a + // commit as $this->connection->inTransaction() will return TRUE. trigger_error('Rollback attempted when there is no active transaction. This can cause data integrity issues.', E_USER_WARNING); return; } @@ -447,15 +451,19 @@ public function rollBack($savepoint_name = 'drupal_transaction') { * {@inheritdoc} */ protected function doCommit() { + // MySQL will automatically commit transactions when tables are altered or + // created (DDL transactions are not supported). On PHP 7 + // $this->connection->commit() does not throw an exception if there is no + // active transaction. This behavior is fixed in PHP 8. In order to maintain + // consistent behavior regardless of PHP version, we check to see if we're + // in transaction before calling commit. if ($this->connection->inTransaction()) { $success = parent::doCommit(); } else { - // On PHP 7 $this->connection->commit() does not throw an exception if - // 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). + // Process the post-root (non-nested) transaction commit callbacks. The + // following code is copied from + // \Drupal\Core\Database\Connection::doCommit() $success = TRUE; if (!empty($this->rootTransactionEndCallbacks)) { $callbacks = $this->rootTransactionEndCallbacks;