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.