diff --git a/src/Illuminate/Database/DatabaseTransactionsManager.php b/src/Illuminate/Database/DatabaseTransactionsManager.php index c730dc503ac2..ee2889a2d18a 100755 --- a/src/Illuminate/Database/DatabaseTransactionsManager.php +++ b/src/Illuminate/Database/DatabaseTransactionsManager.php @@ -83,7 +83,8 @@ public function commit($connection, $levelBeingCommitted, $newTransactionLevel) // shouldn't be any pending transactions, but going to clear them here anyways just // in case. This method could be refactored to receive a level in the future too. $this->pendingTransactions = $this->pendingTransactions->reject( - fn ($transaction) => $transaction->connection === $connection + fn ($transaction) => $transaction->connection === $connection && + $transaction->level >= $levelBeingCommitted )->values(); [$forThisConnection, $forOtherConnections] = $this->committedTransactions->partition( diff --git a/tests/Foundation/Testing/DatabaseTransactionsManagerTest.php b/tests/Foundation/Testing/DatabaseTransactionsManagerTest.php index feac68b8e5bc..82ad8b410bee 100644 --- a/tests/Foundation/Testing/DatabaseTransactionsManagerTest.php +++ b/tests/Foundation/Testing/DatabaseTransactionsManagerTest.php @@ -31,6 +31,23 @@ public function testItIgnoresTheBaseTransactionForCallbackApplicableTransactions $this->assertEquals(2, $manager->callbackApplicableTransactions()[0]->level); } + public function testCommittingDoesNotRemoveTheBasePendingTransaction() + { + $manager = new DatabaseTransactionsManager; + + $manager->begin('foo', 1); + + $manager->begin('foo', 2); + $manager->commit('foo', 2, 1); + + $this->assertCount(0, $manager->callbackApplicableTransactions()); + + $manager->begin('foo', 2); + + $this->assertCount(1, $manager->callbackApplicableTransactions()); + $this->assertEquals(2, $manager->callbackApplicableTransactions()[0]->level); + } + public function testItExecutesCallbacksForTheSecondTransaction() { $testObject = new TestingDatabaseTransactionsManagerTestObject();