Skip to content
Snippets Groups Projects
Commit 62406729 authored by mondrake's avatar mondrake
Browse files

I

parent e8778fb2
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Transaction;
use Drupal\Core\Database\Transaction\StackItem;
use Drupal\Core\Database\Transaction\StackItemType;
use Drupal\Core\Database\TransactionExplicitCommitNotAllowedException;
......@@ -42,6 +43,50 @@ class DriverSpecificTransactionTestBase extends DriverSpecificDatabaseTestBase {
*/
protected ?string $postTransactionCallbackAction = NULL;
/**
* Create a root Drupal transaction.
*/
protected function createRootTransaction(string $name = '', bool $insertRow = TRUE): Transaction {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction($name);
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
if ($insertRow) {
$this->insertRow('David');
$this->assertRowPresent('David');
}
return $transaction;
}
/**
* Create a Drupal savepoint transaction after root.
*/
protected function createFirstSavepointTransaction(string $name = '', bool $insertRow = TRUE): Transaction {
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database. The name can be changed by the $name argument.
$savepoint = $this->connection->startTransaction($name);
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
if ($insertRow) {
$this->insertRow('Roger');
$this->assertRowPresent('Roger');
}
return $savepoint;
}
/**
* Encapsulates a transaction's "inner layer" with an "outer layer".
*
......@@ -153,19 +198,8 @@ protected function transactionInnerLayer($suffix, $rollback = FALSE, $ddl_statem
/**
* Tests root transaction rollback.
*/
public function testRollbackRoot() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
$this->insertRow('David');
$this->assertRowPresent('David');
public function testRollbackRoot(): void {
$transaction = $this->createRootTransaction();
// Rollback. Since we are at the root, the transaction is closed.
// Corresponds to 'ROLLBACK' on the database.
......@@ -178,30 +212,9 @@ public function testRollbackRoot() {
/**
* Tests root transaction rollback after savepoint rollback.
*/
public function testRollbackRootAfterSavepointRollback() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
$this->insertRow('David');
$this->assertRowPresent('David');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
$this->insertRow('Roger');
$this->assertRowPresent('David');
$this->assertRowPresent('Roger');
public function testRollbackRootAfterSavepointRollback(): void {
$transaction = $this->createRootTransaction();
$savepoint = $this->createFirstSavepointTransaction();
// Rollback savepoint. It should get released too. Corresponds to 'ROLLBACK
// TO savepoint_1' plus 'RELEASE savepoint_1' on the database.
......@@ -222,27 +235,11 @@ public function testRollbackRootAfterSavepointRollback() {
/**
* Tests root transaction rollback failure when savepoint is open.
*/
public function testRollbackRootWithActiveSavepoint() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
public function testRollbackRootWithActiveSavepoint(): void {
$transaction = $this->createRootTransaction();
$savepoint = $this->createFirstSavepointTransaction();
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a single row into the testing table.
$this->insertRow('David');
$this->assertRowPresent('David');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Try to rollback root. Since we a savepoint is active, this should fail.
// Try to rollback root. Since a savepoint is active, this should fail.
$this->expectException(TransactionOutOfOrderException::class);
$this->expectExceptionMessageMatches("/^Error attempting rollback of .*\\\\drupal_transaction\\. Active stack: .*\\\\drupal_transaction > .*\\\\savepoint_1/");
$transaction->rollBack();
......@@ -251,30 +248,9 @@ public function testRollbackRootWithActiveSavepoint() {
/**
* Tests savepoint transaction rollback.
*/
public function testRollbackSavepoint() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a row.
$this->insertRow('David');
$this->assertRowPresent('David');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Insert a row.
$this->insertRow('Roger');
$this->assertRowPresent('David');
$this->assertRowPresent('Roger');
public function testRollbackSavepoint(): void {
$transaction = $this->createRootTransaction();
$savepoint = $this->createFirstSavepointTransaction();
// Rollback savepoint. It should get released too. Corresponds to 'ROLLBACK
// TO savepoint_1' plus 'RELEASE savepoint_1' on the database.
......@@ -299,30 +275,9 @@ public function testRollbackSavepoint() {
/**
* Tests savepoint transaction duplicated rollback.
*/
public function testRollbackTwiceSameSavepoint() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Insert a row.
$this->insertRow('David');
$this->assertRowPresent('David');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Insert a row.
$this->insertRow('Roger');
$this->assertRowPresent('David');
$this->assertRowPresent('Roger');
public function testRollbackTwiceSameSavepoint(): void {
$transaction = $this->createRootTransaction();
$savepoint = $this->createFirstSavepointTransaction();
// Rollback savepoint. It should get released too. Corresponds to 'ROLLBACK
// TO savepoint_1' plus 'RELEASE savepoint_1' on the database.
......@@ -354,33 +309,12 @@ public function testRollbackTwiceSameSavepoint() {
/**
* Tests savepoint transaction rollback failure when later savepoints exist.
*/
public function testRollbackSavepointWithLaterSavepoint() {
$this->assertFalse($this->connection->inTransaction());
$this->assertSame(0, $this->connection->transactionManager()->stackDepth());
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
public function testRollbackSavepointWithLaterSavepoint(): void {
$transaction = $this->createRootTransaction();
$savepoint1 = $this->createFirstSavepointTransaction();
// Insert a row.
$this->insertRow('David');
$this->assertRowPresent('David');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint1 = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
// Insert a row.
$this->insertRow('Roger');
$this->assertRowPresent('David');
$this->assertRowPresent('Roger');
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_2'
// on the database.
// Starts another savepoint transaction. Corresponds to 'SAVEPOINT
// savepoint_2' on the database.
$savepoint2 = $this->connection->startTransaction();
$this->assertTrue($this->connection->inTransaction());
$this->assertSame(3, $this->connection->transactionManager()->stackDepth());
......@@ -403,7 +337,7 @@ public function testRollbackSavepointWithLaterSavepoint() {
* The behavior of this test should be identical for connections that support
* transactions and those that do not.
*/
public function testCommittedTransaction() {
public function testCommittedTransaction(): void {
try {
// Create two nested transactions. The changes should be committed.
$this->transactionOuterLayer('A');
......@@ -422,9 +356,9 @@ public function testCommittedTransaction() {
/**
* Tests the compatibility of transactions with DDL statements.
*/
public function testTransactionWithDdlStatement() {
public function testTransactionWithDdlStatement(): void {
// First, test that a commit works normally, even with DDL statements.
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('row');
$this->executeDDLStatement();
unset($transaction);
......@@ -432,7 +366,7 @@ public function testTransactionWithDdlStatement() {
// Even in different order.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->executeDDLStatement();
$this->insertRow('row');
unset($transaction);
......@@ -440,8 +374,8 @@ public function testTransactionWithDdlStatement() {
// Even with stacking.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction2 = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->executeDDLStatement();
unset($transaction2);
$transaction3 = $this->connection->startTransaction();
......@@ -452,8 +386,8 @@ public function testTransactionWithDdlStatement() {
// A transaction after a DDL statement should still work the same.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction2 = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->executeDDLStatement();
unset($transaction2);
$transaction3 = $this->connection->startTransaction();
......@@ -468,7 +402,7 @@ public function testTransactionWithDdlStatement() {
// For database servers that support transactional DDL, a rollback
// of a transaction including DDL statements should be possible.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('row');
$this->executeDDLStatement();
$transaction->rollBack();
......@@ -477,8 +411,8 @@ public function testTransactionWithDdlStatement() {
// Including with stacking.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction2 = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->executeDDLStatement();
unset($transaction2);
$transaction3 = $this->connection->startTransaction();
......@@ -492,7 +426,7 @@ public function testTransactionWithDdlStatement() {
// For database servers that do not support transactional DDL,
// the DDL statement should commit the transaction stack.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('row');
$this->executeDDLStatement();
......@@ -581,11 +515,11 @@ public function assertRowAbsent(string $name, string $message = NULL): void {
/**
* Tests transaction stacking, commit, and rollback.
*/
public function testTransactionStacking() {
public function testTransactionStacking(): void {
// Standard case: pop the inner transaction before the outer transaction.
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('outer');
$transaction2 = $this->connection->startTransaction();
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->insertRow('inner');
// Pop the inner transaction.
unset($transaction2);
......@@ -598,9 +532,9 @@ public function testTransactionStacking() {
// Rollback the inner transaction.
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->insertRow('outer');
$transaction2 = $this->connection->startTransaction();
$transaction2 = $this->createFirstSavepointTransaction('', FALSE);
$this->insertRow('inner');
// Now rollback the inner transaction.
$transaction2->rollBack();
......@@ -618,8 +552,8 @@ public function testTransactionStacking() {
/**
* Tests that transactions can continue to be used if a query fails.
*/
public function testQueryFailureInTransaction() {
$transaction = $this->connection->startTransaction('test_transaction');
public function testQueryFailureInTransaction(): void {
$transaction = $this->createRootTransaction('test_transaction', FALSE);
$this->connection->schema()->dropTable('test');
// Test a failed query using the query() method.
......@@ -737,14 +671,9 @@ public function testQueryFailureInTransaction() {
* Tests releasing a savepoint before last is safe.
*/
public function testReleaseIntermediateSavepoint(): void {
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint1 = $this->connection->startTransaction();
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
$transaction = $this->createRootTransaction();
$savepoint1 = $this->createFirstSavepointTransaction('', FALSE);
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_2'
// on the database.
$savepoint2 = $this->connection->startTransaction();
......@@ -760,7 +689,7 @@ public function testReleaseIntermediateSavepoint(): void {
$this->insertRow('row');
// Unsets a savepoint transaction. Corresponds to 'RELEASE SAVEPOINT
// Commit a savepoint transaction. Corresponds to 'RELEASE SAVEPOINT
// savepoint_2' on the database.
unset($savepoint2);
// Since we have committed an intermediate savepoint Transaction object,
......@@ -768,7 +697,7 @@ public function testReleaseIntermediateSavepoint(): void {
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
$this->assertRowPresent('row');
// Unsets the remaining Transaction objects. The client transaction is
// Commit the remaining Transaction objects. The client transaction is
// eventually committed.
unset($savepoint1);
unset($transaction);
......@@ -780,14 +709,9 @@ public function testReleaseIntermediateSavepoint(): void {
* Tests committing a transaction while savepoints are active.
*/
public function testCommitWithActiveSavepoint(): void {
// Start root transaction. Corresponds to 'BEGIN TRANSACTION' on the
// database.
$transaction = $this->connection->startTransaction();
$this->assertSame(1, $this->connection->transactionManager()->stackDepth());
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_1'
// on the database.
$savepoint1 = $this->connection->startTransaction();
$this->assertSame(2, $this->connection->transactionManager()->stackDepth());
$transaction = $this->createRootTransaction();
$savepoint1 = $this->createFirstSavepointTransaction('', FALSE);
// Starts a savepoint transaction. Corresponds to 'SAVEPOINT savepoint_2'
// on the database.
$savepoint2 = $this->connection->startTransaction();
......@@ -795,7 +719,7 @@ public function testCommitWithActiveSavepoint(): void {
$this->insertRow('row');
// Unsets the root transaction. Corresponds to 'COMMIT' on the database.
// Commit the root transaction. Corresponds to 'COMMIT' on the database.
unset($transaction);
// Since we have committed the outer (root) Transaction object, the inner
// (savepoint) ones have been dropped by the database already, and we are
......@@ -816,10 +740,10 @@ public function testCommitWithActiveSavepoint(): void {
* Tests for transaction names.
*/
public function testTransactionName(): void {
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->assertSame('drupal_transaction', $transaction->name());
$savepoint1 = $this->connection->startTransaction();
$savepoint1 = $this->createFirstSavepointTransaction('', FALSE);
$this->assertSame('savepoint_1', $savepoint1->name());
$this->expectException(TransactionNameNonUniqueException::class);
......@@ -839,8 +763,7 @@ public function testRootTransactionEndCallbackAddedWithoutTransaction(): void {
* Tests post-transaction callback executes after transaction commit.
*/
public function testRootTransactionEndCallbackCalledOnCommit(): void {
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->connection->transactionManager()->addPostTransactionCallback([$this, 'rootTransactionCallback']);
$this->insertRow('row');
$this->assertNull($this->postTransactionCallbackAction);
......@@ -854,8 +777,7 @@ public function testRootTransactionEndCallbackCalledOnCommit(): void {
* Tests post-transaction callback executes after transaction rollback.
*/
public function testRootTransactionEndCallbackCalledOnRollback(): void {
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$transaction = $this->createRootTransaction('', FALSE);
$this->connection->transactionManager()->addPostTransactionCallback([$this, 'rootTransactionCallback']);
$this->insertRow('row');
$this->assertNull($this->postTransactionCallbackAction);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment