function DriverSpecificTransactionTestBase::testTransactionWithDdlStatement

Same name in other branches
  1. 11.x core/tests/Drupal/KernelTests/Core/Database/DriverSpecificTransactionTestBase.php \Drupal\KernelTests\Core\Database\DriverSpecificTransactionTestBase::testTransactionWithDdlStatement()

Tests the compatibility of transactions with DDL statements.

File

core/tests/Drupal/KernelTests/Core/Database/DriverSpecificTransactionTestBase.php, line 362

Class

DriverSpecificTransactionTestBase
Tests the transaction abstraction system.

Namespace

Drupal\KernelTests\Core\Database

Code

public function testTransactionWithDdlStatement() : void {
    // First, test that a commit works normally, even with DDL statements.
    $transaction = $this->createRootTransaction('', FALSE);
    $this->insertRow('row');
    $this->executeDDLStatement();
    unset($transaction);
    $this->assertRowPresent('row');
    // Even in different order.
    $this->cleanUp();
    $transaction = $this->createRootTransaction('', FALSE);
    $this->executeDDLStatement();
    $this->insertRow('row');
    unset($transaction);
    $this->assertRowPresent('row');
    // Even with stacking.
    $this->cleanUp();
    $transaction = $this->createRootTransaction('', FALSE);
    $transaction2 = $this->createFirstSavepointTransaction('', FALSE);
    $this->executeDDLStatement();
    unset($transaction2);
    $transaction3 = $this->connection
        ->startTransaction();
    $this->insertRow('row');
    unset($transaction3);
    unset($transaction);
    $this->assertRowPresent('row');
    // A transaction after a DDL statement should still work the same.
    $this->cleanUp();
    $transaction = $this->createRootTransaction('', FALSE);
    $transaction2 = $this->createFirstSavepointTransaction('', FALSE);
    $this->executeDDLStatement();
    unset($transaction2);
    $transaction3 = $this->connection
        ->startTransaction();
    $this->insertRow('row');
    $transaction3->rollBack();
    unset($transaction3);
    unset($transaction);
    $this->assertRowAbsent('row');
    // The behavior of a rollback depends on the type of database server.
    if ($this->connection
        ->supportsTransactionalDDL()) {
        // For database servers that support transactional DDL, a rollback
        // of a transaction including DDL statements should be possible.
        $this->cleanUp();
        $transaction = $this->createRootTransaction('', FALSE);
        $this->insertRow('row');
        $this->executeDDLStatement();
        $transaction->rollBack();
        unset($transaction);
        $this->assertRowAbsent('row');
        // Including with stacking.
        $this->cleanUp();
        $transaction = $this->createRootTransaction('', FALSE);
        $transaction2 = $this->createFirstSavepointTransaction('', FALSE);
        $this->executeDDLStatement();
        unset($transaction2);
        $transaction3 = $this->connection
            ->startTransaction();
        $this->insertRow('row');
        unset($transaction3);
        $transaction->rollBack();
        unset($transaction);
        $this->assertRowAbsent('row');
    }
    else {
        // For database servers that do not support transactional DDL,
        // the DDL statement should commit the transaction stack.
        $this->cleanUp();
        $transaction = $this->createRootTransaction('', FALSE);
        $this->insertRow('row');
        $this->executeDDLStatement();
        // Try to rollback the outer transaction. It should fail and void
        // the transaction stack.
        $transaction->rollBack();
        $manager = $this->connection
            ->transactionManager();
        $reflectedTransactionState = new \ReflectionMethod($manager, 'getConnectionTransactionState');
        $this->assertSame(ClientConnectionTransactionState::Voided, $reflectedTransactionState->invoke($manager));
        unset($transaction);
        $this->assertRowPresent('row');
    }
}

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