function TransactionTest::testTransactionWithDdlStatement
Same name in other branches
- 9 core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php \Drupal\KernelTests\Core\Database\TransactionTest::testTransactionWithDdlStatement()
- 8.9.x core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php \Drupal\KernelTests\Core\Database\TransactionTest::testTransactionWithDdlStatement()
Tests the compatibility of transactions with DDL statements.
File
-
core/
tests/ Drupal/ KernelTests/ Core/ Database/ TransactionTest.php, line 489
Class
- TransactionTest
- Tests the transactions, using the explicit ::commitOrRelease method.
Namespace
Drupal\KernelTests\Core\DatabaseCode
public function testTransactionWithDdlStatement() : void {
// First, test that a commit works normally, even with DDL statements.
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('row');
$this->executeDDLStatement();
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('row');
// Even in different order.
$this->cleanUp();
$transaction = $this->createRootTransaction('', FALSE);
$this->executeDDLStatement();
$this->insertRow('row');
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('row');
// Even with stacking.
$this->cleanUp();
$transaction = $this->createRootTransaction('', FALSE);
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->executeDDLStatement();
if ($this->connection
->supportsTransactionalDDL()) {
$transaction2->commitOrRelease();
}
else {
set_error_handler(static function (int $errno, string $errstr) : bool {
throw new \ErrorException($errstr);
});
try {
$transaction2->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();
}
}
$transaction3 = $this->connection
->startTransaction();
$this->insertRow('row');
$transaction3->commitOrRelease();
if ($this->connection
->supportsTransactionalDDL()) {
$transaction->commitOrRelease();
}
else {
try {
$transaction->commitOrRelease();
$this->fail('TransactionOutOfOrderException was expected, but did not throw.');
} catch (TransactionOutOfOrderException) {
// Just continue, this is out or order since $transaction3 started a
// new root.
}
}
$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();
if ($this->connection
->supportsTransactionalDDL()) {
$transaction2->commitOrRelease();
}
else {
set_error_handler(static function (int $errno, string $errstr) : bool {
throw new \ErrorException($errstr);
});
try {
$transaction2->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();
}
}
$transaction3 = $this->connection
->startTransaction();
$this->insertRow('row');
$transaction3->rollBack();
if ($this->connection
->supportsTransactionalDDL()) {
$transaction->commitOrRelease();
}
else {
try {
$transaction->commitOrRelease();
$this->fail('TransactionOutOfOrderException was expected, but did not throw.');
} catch (TransactionOutOfOrderException) {
// Just continue, this is out or order since $transaction3 started a
// new root.
}
}
$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();
$this->assertRowAbsent('row');
// Including with stacking.
$this->cleanUp();
$transaction = $this->createRootTransaction('', FALSE);
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->executeDDLStatement();
$transaction2->commitOrRelease();
$transaction3 = $this->connection
->startTransaction();
$this->insertRow('row');
$transaction3->commitOrRelease();
$this->assertRowPresent('row');
$transaction->rollBack();
$this->assertRowAbsent('row');
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.