function TransactionTest::testTransactionStacking
Same name in other branches
- 9 core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php \Drupal\KernelTests\Core\Database\TransactionTest::testTransactionStacking()
Tests transaction stacking, commit, and rollback.
File
-
core/
tests/ Drupal/ KernelTests/ Core/ Database/ TransactionTest.php, line 381
Class
- TransactionTest
- Tests the transaction abstraction system.
Namespace
Drupal\KernelTests\Core\DatabaseCode
public function testTransactionStacking() {
// This test won't work right if transactions are not supported.
if (!$this->connection
->supportsTransactions()) {
$this->markTestSkipped("The '{$this->connection->driver()}' database driver does not support transactions.");
}
// Standard case: pop the inner transaction before the outer transaction.
$transaction = $this->connection
->startTransaction();
$this->insertRow('outer');
$transaction2 = $this->connection
->startTransaction();
$this->insertRow('inner');
// Pop the inner transaction.
unset($transaction2);
$this->assertTrue($this->connection
->inTransaction(), 'Still in a transaction after popping the inner transaction');
// Pop the outer transaction.
unset($transaction);
$this->assertFalse($this->connection
->inTransaction(), 'Transaction closed after popping the outer transaction');
$this->assertRowPresent('outer');
$this->assertRowPresent('inner');
// Pop the transaction in a different order they have been pushed.
$this->cleanUp();
$transaction = $this->connection
->startTransaction();
$this->insertRow('outer');
$transaction2 = $this->connection
->startTransaction();
$this->insertRow('inner');
// Pop the outer transaction, nothing should happen.
unset($transaction);
$this->insertRow('inner-after-outer-commit');
$this->assertTrue($this->connection
->inTransaction(), 'Still in a transaction after popping the outer transaction');
// Pop the inner transaction, the whole transaction should commit.
unset($transaction2);
$this->assertFalse($this->connection
->inTransaction(), 'Transaction closed after popping the inner transaction');
$this->assertRowPresent('outer');
$this->assertRowPresent('inner');
$this->assertRowPresent('inner-after-outer-commit');
// Rollback the inner transaction.
$this->cleanUp();
$transaction = $this->connection
->startTransaction();
$this->insertRow('outer');
$transaction2 = $this->connection
->startTransaction();
$this->insertRow('inner');
// Now rollback the inner transaction.
$transaction2->rollBack();
unset($transaction2);
$this->assertTrue($this->connection
->inTransaction(), 'Still in a transaction after popping the outer transaction');
// Pop the outer transaction, it should commit.
$this->insertRow('outer-after-inner-rollback');
unset($transaction);
$this->assertFalse($this->connection
->inTransaction(), 'Transaction closed after popping the inner transaction');
$this->assertRowPresent('outer');
$this->assertRowAbsent('inner');
$this->assertRowPresent('outer-after-inner-rollback');
// Rollback the inner transaction after committing the outer one.
$this->cleanUp();
$transaction = $this->connection
->startTransaction();
$this->insertRow('outer');
$transaction2 = $this->connection
->startTransaction();
$this->insertRow('inner');
// Pop the outer transaction, nothing should happen.
unset($transaction);
$this->assertTrue($this->connection
->inTransaction(), 'Still in a transaction after popping the outer transaction');
// Now rollback the inner transaction, it should rollback.
$transaction2->rollBack();
unset($transaction2);
$this->assertFalse($this->connection
->inTransaction(), 'Transaction closed after popping the inner transaction');
$this->assertRowPresent('outer');
$this->assertRowAbsent('inner');
// Rollback the outer transaction while the inner transaction is active.
// In that case, an exception will be triggered because we cannot
// ensure that the final result will have any meaning.
$this->cleanUp();
$transaction = $this->connection
->startTransaction();
$this->insertRow('outer');
$transaction2 = $this->connection
->startTransaction();
$this->insertRow('inner');
$transaction3 = $this->connection
->startTransaction();
$this->insertRow('inner2');
// Rollback the outer transaction.
try {
$transaction->rollBack();
unset($transaction);
$this->fail('Rolling back the outer transaction while the inner transaction is active resulted in an exception.');
} catch (TransactionOutOfOrderException $e) {
// Expected exception; just continue testing.
}
$this->assertFalse($this->connection
->inTransaction(), 'No more in a transaction after rolling back the outer transaction');
// Try to commit one inner transaction.
unset($transaction3);
// Try to rollback one inner transaction.
try {
$transaction->rollBack();
unset($transaction2);
$this->fail('Trying to commit an inner transaction resulted in an exception.');
} catch (TransactionNoActiveException $e) {
// Expected exception; just continue testing.
}
$this->assertRowAbsent('outer');
$this->assertRowAbsent('inner');
$this->assertRowAbsent('inner2');
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.