-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Closed
Closed
Copy link
Labels
Description
Laravel Version
10.32.1
PHP Version
8.2
Description
When a child transaction is committed inside of a parent transaction, any events with the ShouldDispatchAfterCommit
interface that are dispatched after the child transaction has committed, but before the parent transaction is committed, will be dispatched immediately.
The problem is related to that the dispatcher adds the event listeners using DatabaseTransactionManager@addCallback
, and that this method only adds the callback if it has any pendingTransactions
- which are flushed whenever a transaction is committed.
Steps To Reproduce
I wrote a failing test case in ShouldDispatchAfterCommitEventTest.php
that illustrates the problem:
public function testItOnlyDispatchesEventsAfterTheRootTransactionIsCommitted()
{
Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);
DB::transaction(function () {
// Begin and commit a child transaction. This line causes the test to fail.
DB::transaction(function () {});
Event::dispatch(new ShouldDispatchAfterCommitTestEvent);
$this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);
});
$this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);
}
kyryl-bogach