function TransactionManagerBase::rollback

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

Rolls back a Drupal transaction.

Rollbacks for nested transactions need to occur in reverse order to the pushes to the stack. Rolling back the last active Drupal transaction leads to rolling back the client connection (or to committing it in the edge case when the root was unpiled earlier).

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::rollback

File

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

Class

TransactionManagerBase
The database transaction manager base class.

Namespace

Drupal\Core\Database\Transaction

Code

public function rollback(string $name, string $id) : void {
    // @todo remove in drupal:11.0.0.
    // Start of BC layer.
    if ($id === 'bc-force-rollback') {
        foreach ($this->stack() as $stackId => $item) {
            if ($item->name === $name) {
                $id = $stackId;
                break;
            }
        }
        if ($id === 'bc-force-rollback') {
            throw new TransactionOutOfOrderException();
        }
    }
    // End of BC layer.
    // Rolled back item should match the last one in stack.
    if ($id != array_key_last($this->stack()) || $name !== $this->stack()[$id]->name) {
        throw new TransactionOutOfOrderException("Error attempting rollback of {$id}\\{$name}. Active stack: " . $this->dumpStackItemsAsString());
    }
    if ($this->getConnectionTransactionState() === ClientConnectionTransactionState::Active) {
        if ($this->stackDepth() > 1 && $this->stack()[$id]->type === StackItemType::Savepoint) {
            // Rollback the client transaction to the savepoint when the Drupal
            // transaction is not a root one. Then, release the savepoint too. The
            // client connection remains active.
            $this->rollbackClientSavepoint($name);
            $this->releaseClientSavepoint($name);
            // The Transaction object remains open, and when it will get destructed
            // no commit should happen. Void the stack item.
            $this->voidStackItem($id);
        }
        elseif ($this->stackDepth() === 1 && $this->stack()[$id]->type === StackItemType::Root) {
            // If this was the root Drupal transaction, we can rollback the client
            // transaction. The transaction is closed.
            $this->processRootRollback();
            if ($this->getConnectionTransactionState() === ClientConnectionTransactionState::RolledBack) {
                // The Transaction object remains open, and when it will get destructed
                // no commit should happen. Void the stack item.
                $this->voidStackItem($id);
            }
        }
        else {
            // The stack got corrupted.
            throw new TransactionOutOfOrderException("Error attempting rollback of {$id}\\{$name}. Active stack: " . $this->dumpStackItemsAsString());
        }
        return;
    }
    // The stack got corrupted.
    throw new TransactionOutOfOrderException("Error attempting rollback of {$id}\\{$name}. Active stack: " . $this->dumpStackItemsAsString());
}

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