framework
framework copied to clipboard
[10.x] After commit callback throwing an exception causes transaction level to be incorrect
Hey.
Whenever an afterCommit callback throws an exception inside of a DB::transaction() closure, it's caught by the ManagesTransactions trait and internal ->transactions transaction level is decremented. In tests that use DatabaseTransactions trait this makes DB::transactionLevel() return 0, although the real transaction level (on the database side) is still 1.
class SomeTest extends TestCase
{
use DatabaseTransactions;
public function testSomething()
{
$this->assertSame(1, DB::transactionLevel());
try {
DB::transaction(function () {
$this->assertSame(2, DB::transactionLevel());
DB::afterCommit(fn () => throw new \RuntimeException());
});
} catch (\RuntimeException) {}
// Currently fails
$this->assertSame(1, DB::transactionLevel());
}
}
This PR fixes this by running after commit callbacks outside of the try-catch, next to the "committing" event.