-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.x] Transaction aware code execution #35373
Conversation
What about this way? https://github.com/fntneves/laravel-transactional-events |
Wouldn't it be more like an PS: the Solved: 04df2e1 |
What if we dispatched the I know this would be a breaking change but it always felt strange to me that certain eloquent events are dispatched even if the data is not actually persisted yet. |
@TitasGailius and how would you run logic that has to be done after the model is created but inside the same transaction? |
@Gummibeer oh, I see. Good point. 👍 |
Just so I understand, this means the listener code like in your example must be aware that it is run within a transaction? |
Maybe UserCommitted/UserPersisted event that runs when the transaction the user is created is committed/persisted? |
@taylorotwell this PR introduces a generic function to make code execution transaction-ware. In future PRs, we can add config values to make listeners, jobs, mail, etc... transaction-aware by default. |
What about being able to assign a name to database transactions inside of the For example (pseudo API): DB::transaction('user.creation', $callback)
DB::afterCommit('user.creation', $callback) Then it is immediately clear that the callback is associated with a specific transaction. Thoughts? |
I find I really strange to have it as a function. Personally I would like to ser this as a trait or something similar. |
This guy made this https://github.com/fntneves/laravel-transactional-events, I've been using for years and this maybe is the opportunity to make it native in the core of Laravel. |
I believe it's better to just leave it at the callbacks (after commit / rollback) and provide an out-of-the-box functionality for jobs/queue dispatches to be transaction-aware. Extending the same for events (for example) may not be very intuitive. Many events may want to run within the same transaction. And if the events/mail, etc. are |
What happens if this is running without an enclosing transaction? |
@mfn the code will be executed rightaway if there's no transaction. |
I would just like some clarification on this. What would be the outcome in this scenario: DB::transaction(function() {
$user = User::create();
$profile = DB::transaction(function() use ($user) {
$model = Profile::create(['user_id' => $user->id]);
DB::afterCommit(function() {
echo 1;
});
return $model;
});
DB::afterCommit(function() {
echo 2;
});
return $user;
}); I'm assuming the whole transaction would commit, then it would echo 1 then 2. |
@themsaid Sorry for bothering, I just need a confirmation. Why listener that implements ShouldQueue and use Sync driver is not dispatched after transaction commit, even when I set But, when the listener doesn't implement ShouldQueue, it would dispatched after transaction commit. Any reason? |
This PR is a followup on #35266 and the functionality introduced here, if merged, will be used in the other PR.
So, this PR introduces a transaction manager class that records transactions, commits, and rollbacks. It also records code execution that should be transaction aware. This code will only be executed after transactions are committed and will be discarded if transactions were rolled back.
Now imagine there's a listener registered on the
user.created
eloquent event that sends a welcome email. Inside the listener, you can do this:The callback passed to
afterCommit
will be stored in a local cache and will be executed once the transaction is committed. If the transaction was rolledback, the callback will be discarded.