function TransactionManagerBase::unpile

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Database/Transaction/TransactionManagerBase.php \Drupal\Core\Database\Transaction\TransactionManagerBase::unpile()

Removes a Drupal transaction from the stack.

The unpiled item does not necessarily need to be the last on the stack. This method should only be called by a Transaction object going out of scope.

This method should only be called internally by a database driver.

Parameters

string $name: The name of the transaction.

string $id: The id of the transaction.

Overrides TransactionManagerInterface::unpile

1 call to TransactionManagerBase::unpile()
TransactionManagerBase::commitAll in core/lib/Drupal/Core/Database/Transaction/TransactionManagerBase.php
Commits the entire transaction stack.

File

core/lib/Drupal/Core/Database/Transaction/TransactionManagerBase.php, line 289

Class

TransactionManagerBase
The database transaction manager base class.

Namespace

Drupal\Core\Database\Transaction

Code

public function unpile(string $name, string $id) : void {
  // If this is a 'root' transaction, and it is voided (that is, no longer in
  // the stack), then the transaction on the database is no longer active. An
  // action such as a rollback, or a DDL statement, was executed that
  // terminated the database transaction. So, we can process the post
  // transaction callbacks.
  if (!isset($this->stack()[$id]) && isset($this->voidedItems[$id]) && $this->rootId === $id) {
    $this->processPostTransactionCallbacks();
    $this->rootId = NULL;
    unset($this->voidedItems[$id]);
    return;
  }
  // If the $id does not correspond to the one in the stack for that $name,
  // we are facing an orphaned Transaction object (for example in case of a
  // DDL statement breaking an active transaction). That should be listed in
  // $voidedItems, so we can remove it from there.
  if (!isset($this->stack()[$id]) || $this->stack()[$id]->name !== $name) {
    unset($this->voidedItems[$id]);
    return;
  }
  // If we are not releasing the last savepoint but an earlier one, or
  // committing a root transaction while savepoints are active, all
  // subsequent savepoints will be released as well. The stack must be
  // diminished accordingly.
  while (($i = array_key_last($this->stack())) != $id) {
    $this->voidStackItem((string) $i);
  }
  if ($this->getConnectionTransactionState() === ClientConnectionTransactionState::Active) {
    if ($this->stackDepth() > 1 && $this->stack()[$id]->type === StackItemType::Savepoint) {
      // Release the client transaction savepoint in case the Drupal
      // transaction is not a root one.
      $this->releaseClientSavepoint($name);
    }
    elseif ($this->stackDepth() === 1 && $this->stack()[$id]->type === StackItemType::Root) {
      // If this was the root Drupal transaction, we can commit the client
      // transaction.
      $this->processRootCommit();
      if ($this->rootId === $id) {
        $this->processPostTransactionCallbacks();
        $this->rootId = NULL;
      }
    }
    else {
      // The stack got corrupted.
      throw new TransactionOutOfOrderException("Transaction {$id}/{$name} is out of order. Active stack: " . $this->dumpStackItemsAsString());
    }
    // Remove the transaction from the stack.
    $this->removeStackItem($id);
    return;
  }
  // The stack got corrupted.
  throw new TransactionOutOfOrderException("Transaction {$id}/{$name} is out of order. Active stack: " . $this->dumpStackItemsAsString());
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.