Execute code outside of transaction only when it commits in Laravel 8.x

Amit Merchant · December 3, 2020 ·

Sometimes, there might be a case where you would want some of the code that lies outside of the transaction to be executed only when the corresponding transaction commits successfully and if in any case, it’s a rollback, that code shouldn’t be executed.

Well, Laravel has just added the ability to do the same. This PR in Laravel v8.17.0 by Mohamed Said introduces a transaction manager class that records transactions, commits, and rollbacks. It also records code execution that should be transaction aware using the DB::afterCommit method.

You can write the code to be executed inside the closure that you would need to pass to the DB::afterCommit method.

Using DB::afterCommit method

Quoting the PR, let’s say we have the following code which incorporates a User model, wrapped around by a transaction…

DB::transaction(function () {
    $user = User::create([...]);

    $user->teams()->create([...]);
});

Now, you have a code outside of this transaction that you want to be executed once the transaction is committed and discarded when it rolls back. For instance, there’s a listener registered on the user.created Eloquent event that sends a welcome email. Inside the listener, you can write that code in the DB::afterCommit method like so.

public function handle()
{
    DB::afterCommit(function () {
        Mail::send(...);
    });
}

Note here that, this code will still work in cases when there’s no enclosing transaction as the code will be executed right away.

Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!