Chris@0: startTransaction(), from the appropriate connection Chris@0: * object. Chris@0: */ Chris@0: class Transaction { Chris@0: Chris@0: /** Chris@0: * The connection object for this transaction. Chris@0: * Chris@0: * @var \Drupal\Core\Database\Connection Chris@0: */ Chris@0: protected $connection; Chris@0: Chris@0: /** Chris@0: * A boolean value to indicate whether this transaction has been rolled back. Chris@0: * Chris@0: * @var bool Chris@0: */ Chris@0: protected $rolledBack = FALSE; Chris@0: Chris@0: /** Chris@0: * The name of the transaction. Chris@0: * Chris@0: * This is used to label the transaction savepoint. It will be overridden to Chris@0: * 'drupal_transaction' if there is no transaction depth. Chris@0: */ Chris@0: protected $name; Chris@0: Chris@0: public function __construct(Connection $connection, $name = NULL) { Chris@0: $this->connection = $connection; Chris@0: // If there is no transaction depth, then no transaction has started. Name Chris@0: // the transaction 'drupal_transaction'. Chris@0: if (!$depth = $connection->transactionDepth()) { Chris@0: $this->name = 'drupal_transaction'; Chris@0: } Chris@0: // Within transactions, savepoints are used. Each savepoint requires a Chris@0: // name. So if no name is present we need to create one. Chris@0: elseif (!$name) { Chris@0: $this->name = 'savepoint_' . $depth; Chris@0: } Chris@0: else { Chris@0: $this->name = $name; Chris@0: } Chris@0: $this->connection->pushTransaction($this->name); Chris@0: } Chris@0: Chris@0: public function __destruct() { Chris@0: // If we rolled back then the transaction would have already been popped. Chris@0: if (!$this->rolledBack) { Chris@0: $this->connection->popTransaction($this->name); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieves the name of the transaction or savepoint. Chris@0: */ Chris@0: public function name() { Chris@0: return $this->name; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Rolls back the current transaction. Chris@0: * Chris@0: * This is just a wrapper method to rollback whatever transaction stack we are Chris@0: * currently in, which is managed by the connection object itself. Note that Chris@0: * logging (preferable with watchdog_exception()) needs to happen after a Chris@0: * transaction has been rolled back or the log messages will be rolled back Chris@0: * too. Chris@0: * Chris@0: * @see \Drupal\Core\Database\Connection::rollBack() Chris@0: * @see watchdog_exception() Chris@0: */ Chris@0: public function rollBack() { Chris@0: $this->rolledBack = TRUE; Chris@0: $this->connection->rollBack($this->name); Chris@0: } Chris@0: Chris@0: }