diff --git a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php index 1d8aa90d45..ce40116c53 100644 --- a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php +++ b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php @@ -20,9 +20,14 @@ * Callback to be invoked just after a database transaction gets committed. * * Executes all delayed tag invalidations. + * + * @param bool $success + * Whether or not the transaction was successful. */ - public function rootTransactionEndCallback() { - $this->doInvalidateTags($this->delayedTags); + public function rootTransactionEndCallback($success) { + if ($success) { + $this->doInvalidateTags($this->delayedTags); + } $this->delayedTags = []; } diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php index 59e269647a..ca1f5ac156 100644 --- a/core/lib/Drupal/Core/Database/Connection.php +++ b/core/lib/Drupal/Core/Database/Connection.php @@ -1224,12 +1224,18 @@ public function popTransaction($name) { * Memcache cache implementations can replicate the transaction-behavior of * the database cache backend and avoid race conditions. * + * An argument is passed to the callbacks that indicates whether the + * transaction was successful or not. + * * @param callable $callback * The callback to invoke. * * @see \Drupal\Core\Database\Connection::doCommit() */ public function addRootTransactionEndCallback(callable $callback) { + if (!$this->transactionLayers) { + throw new \LogicException('Root transaction end callbacks can only be added when there is an active transaction.'); + } $this->rootTransactionEndCallbacks[] = $callback; } @@ -1258,19 +1264,22 @@ protected function popCommittableTransactions() { } /** - * Do the actual commit, invoke pre-commit callbacks. + * Do the actual commit, invoke post-commit callbacks. * * @internal */ protected function doCommit() { - if (!$this->connection->commit()) { - throw new TransactionCommitFailedException(); - } + $success = $this->connection->commit(); if (!empty($this->rootTransactionEndCallbacks)) { - foreach($this->rootTransactionEndCallbacks as $callback) { - call_user_func($callback); - } + $callbacks = $this->rootTransactionEndCallbacks; $this->rootTransactionEndCallbacks = []; + foreach($callbacks as $callback) { + call_user_func($callback, $success); + } + } + + if (!$success) { + throw new TransactionCommitFailedException(); } }