function TransactionTest::testCommitAfterDdl

Tests commit does not fail when committing after DDL.

In core, SQLite and PostgreSql databases support transactional DDL, MySql does not.

File

core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php, line 408

Class

TransactionTest
Tests the transactions, using the explicit ::commitOrRelease method.

Namespace

Drupal\KernelTests\Core\Database

Code

public function testCommitAfterDdl() : void {
    $transaction = $this->createRootTransaction();
    $savepoint = $this->createFirstSavepointTransaction();
    $this->executeDDLStatement();
    $this->assertRowPresent('David');
    $this->assertRowPresent('Roger');
    if ($this->connection
        ->supportsTransactionalDDL()) {
        $this->assertTrue($this->connection
            ->inTransaction());
        $this->assertSame(2, $this->connection
            ->transactionManager()
            ->stackDepth());
    }
    else {
        $this->assertFalse($this->connection
            ->inTransaction());
    }
    $this->assertRowPresent('David');
    $this->assertRowPresent('Roger');
    if ($this->connection
        ->supportsTransactionalDDL()) {
        $savepoint->commitOrRelease();
        $this->assertTrue($this->connection
            ->inTransaction());
        $this->assertSame(1, $this->connection
            ->transactionManager()
            ->stackDepth());
    }
    else {
        set_error_handler(static function (int $errno, string $errstr) : bool {
            throw new \ErrorException($errstr);
        });
        try {
            $savepoint->commitOrRelease();
        } catch (\ErrorException $e) {
            $this->assertSame('Transaction::commitOrRelease() was not processed because a prior execution of a DDL statement already committed the transaction.', $e->getMessage());
        } finally {
            restore_error_handler();
        }
        $this->assertFalse($this->connection
            ->inTransaction());
    }
    if ($this->connection
        ->supportsTransactionalDDL()) {
        $transaction->commitOrRelease();
    }
    else {
        set_error_handler(static function (int $errno, string $errstr) : bool {
            throw new \ErrorException($errstr);
        });
        try {
            $transaction->commitOrRelease();
        } catch (\ErrorException $e) {
            $this->assertSame('Transaction::commitOrRelease() was not processed because a prior execution of a DDL statement already committed the transaction.', $e->getMessage());
        } finally {
            restore_error_handler();
        }
    }
    $this->assertRowPresent('David');
    $this->assertRowPresent('Roger');
    $this->assertFalse($this->connection
        ->inTransaction());
}

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