0 follower

Abstract Class Yiisoft\Db\Driver\Pdo\AbstractPdoTransaction

InheritanceYiisoft\Db\Driver\Pdo\AbstractPdoTransaction
ImplementsPsr\Log\LoggerAwareInterface, Yiisoft\Db\Transaction\TransactionInterface
Uses TraitsPsr\Log\LoggerAwareTrait

Represents a DB transaction.

A transaction is a set of SQL statements that must either all succeed or all fail.

It's usually created by calling {@see \Yiisoft\Db\Connection\AbstractConnectionAbstractConnection::beginTransaction()}.

The following code is a typical example of using transactions (note that some DBMS may not support transactions):

$transaction = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
    $connection->createCommand($sql2)->execute();
    // ... other SQL executions
    $transaction->commit();
} catch (\Throwable $e) {
    $transaction->rollBack();
    throw $e;
}

Protected Methods

Hide inherited methods

Method Description Defined By
setTransactionIsolationLevel() Sets the transaction isolation level. Yiisoft\Db\Driver\Pdo\AbstractPdoTransaction

Constants

Hide inherited constants

Constant Value Description Defined By
READ_COMMITTED 'READ COMMITTED' A constant representing the transaction isolation level READ COMMITTED. Yiisoft\Db\Transaction\TransactionInterface
READ_UNCOMMITTED 'READ UNCOMMITTED' A constant representing the transaction isolation level READ UNCOMMITTED. Yiisoft\Db\Transaction\TransactionInterface
REPEATABLE_READ 'REPEATABLE READ' A constant representing the transaction isolation level REPEATABLE READ. Yiisoft\Db\Transaction\TransactionInterface
SERIALIZABLE 'SERIALIZABLE' A constant representing the transaction isolation level SERIALIZABLE. Yiisoft\Db\Transaction\TransactionInterface

Property Details

Method Details

Hide inherited methods

__construct() public method

public mixed __construct ( Yiisoft\Db\Driver\Pdo\PdoConnectionInterface $db )
$db Yiisoft\Db\Driver\Pdo\PdoConnectionInterface

                public function __construct(protected PdoConnectionInterface $db) {}

            
begin() public method

public void begin ( string|null $isolationLevel null )
$isolationLevel string|null

                public function begin(?string $isolationLevel = null): void
{
    $this->db->open();
    if ($this->level === 0) {
        if ($isolationLevel !== null) {
            $this->setTransactionIsolationLevel($isolationLevel);
        }
        $this->logger?->log(
            LogLevel::DEBUG,
            'Begin transaction' . ($isolationLevel ? ' with isolation level ' . $isolationLevel : '')
            . ' ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->db->getPdo()?->beginTransaction();
        $this->level = 1;
        return;
    }
    if ($this->db->isSavepointEnabled()) {
        $this->logger?->log(
            LogLevel::DEBUG,
            'Set savepoint ' . $this->level . ' ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->createSavepoint('LEVEL' . $this->level);
    } else {
        $this->logger?->log(
            LogLevel::DEBUG,
            'Transaction not started: nested transaction not supported ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        throw new NotSupportedException('Transaction not started: nested transaction not supported.');
    }
    $this->level++;
}

            
commit() public method

public void commit ( )

                public function commit(): void
{
    if (!$this->isActive()) {
        throw new Exception('Failed to commit transaction: transaction was inactive.');
    }
    $this->level--;
    if ($this->level === 0) {
        $this->logger?->log(
            LogLevel::DEBUG,
            'Commit transaction ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->db->getPdo()?->commit();
        return;
    }
    if ($this->db->isSavepointEnabled()) {
        $this->logger?->log(
            LogLevel::DEBUG,
            'Release savepoint ' . $this->level . ' ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->releaseSavepoint('LEVEL' . $this->level);
    } else {
        $this->logger?->log(
            LogLevel::INFO,
            'Transaction not committed: nested transaction not supported ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
    }
}

            
createSavepoint() public method

public void createSavepoint ( string $name )
$name string

                public function createSavepoint(string $name): void
{
    $this->db->createCommand("SAVEPOINT $name")->execute();
}

            
getLevel() public method

public integer getLevel ( )

                public function getLevel(): int
{
    return $this->level;
}

            
isActive() public method

public boolean isActive ( )

                public function isActive(): bool
{
    /** Extra check pdo->inTransaction {@link https://github.com/yiisoft/yii2/pull/18407/} */
    return $this->level > 0 && $this->db->isActive() && $this->db->getPdo()?->inTransaction();
}

            
releaseSavepoint() public method

public void releaseSavepoint ( string $name )
$name string

                public function releaseSavepoint(string $name): void
{
    $this->db->createCommand("RELEASE SAVEPOINT $name")->execute();
}

            
rollBack() public method

public void rollBack ( )

                public function rollBack(): void
{
    if (!$this->isActive()) {
        /**
         * Do nothing if a transaction isn't active: this could be the transaction is committed but the event
         * handler to "commitTransaction" throw an exception
         */
        return;
    }
    $this->level--;
    if ($this->level === 0) {
        $this->logger?->log(
            LogLevel::INFO,
            'Roll back transaction ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->db->getPdo()?->rollBack();
        return;
    }
    if ($this->db->isSavepointEnabled()) {
        $this->logger?->log(
            LogLevel::DEBUG,
            'Roll back to savepoint ' . $this->level . ' ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
        $this->rollBackSavepoint('LEVEL' . $this->level);
    } else {
        $this->logger?->log(
            LogLevel::INFO,
            'Transaction not rolled back: nested transaction not supported ' . __METHOD__,
            ['type' => LogType::TRANSACTION],
        );
    }
}

            
rollBackSavepoint() public method

public void rollBackSavepoint ( string $name )
$name string

                public function rollBackSavepoint(string $name): void
{
    $this->db->createCommand("ROLLBACK TO SAVEPOINT $name")->execute();
}

            
setIsolationLevel() public method

public void setIsolationLevel ( string $level )
$level string

                public function setIsolationLevel(string $level): void
{
    if (!$this->isActive()) {
        throw new Exception('Failed to set isolation level: transaction was inactive.');
    }
    $this->logger?->log(
        LogLevel::DEBUG,
        'Setting transaction isolation level to ' . $this->level . ' ' . __METHOD__,
        ['type' => LogType::TRANSACTION],
    );
    $this->setTransactionIsolationLevel($level);
}

            
setTransactionIsolationLevel() protected method

Sets the transaction isolation level.

protected void setTransactionIsolationLevel ( string $level )
$level string
throws Yiisoft\Db\Exception\Exception
throws Yiisoft\Db\Exception\InvalidConfigException
throws Throwable

                protected function setTransactionIsolationLevel(string $level): void
{
    $this->db->createCommand("SET TRANSACTION ISOLATION LEVEL $level")->execute();
}