What is the transaction method on the DB facade in Laravel, and how can it help you build a more bulletproof application?
It's common for me to have to run a series of queries on my applications' database. Typically, I'm also looking to make sure that if any of those create/update/delete operations fail, the application can roll back any changes that were made. Manually doing this at the application layer can be challenging, tedious, and borderline impossible depending on your system's setup. But thankfully, Laravel has a fantastic way to solve exactly that problem.
Laravel's DB
facade contains a lot of really useful abstractions for your database
management system of choice. The one I want to focus in on is the transaction
method.
A great usage example of the transaction
method can be found in the DeleteUser
action that comes along with Laravel Jetstream:
public function delete($user)
{
DB::transaction(function () use ($user) {
$this->deleteTeams($user);
$user->deleteProfilePhoto();
$user->tokens->each->delete();
$user->delete();
});
}
So what does the transaction
method DO, exactly?
Let's start with the closure function. For the most part, the code in here runs
exactly like it would anywhere else in your Laravel application, except for one
special feature you get because of the transaction
method: rollbacks.
Like I mentioned earlier, these are a series of database queries that I would
want to make sure were only finalized if all of them passed. If that wasn't the
case, we could end up in a state where, for a given User
, we could have deleted
their Teams
, but failed to delete their profile photo, tokens, and the User
themselves. Not an idea scenario, to say the least.
But, since this series of database queries has been wrapped into the transaction
method, if any one of them fails, all of the queries up until that point are
rolled back, and none of the queries in the transaction are committed to the
database. So in the previous scenario, were the deletion of the User's
profile
photo to fail, their teams would no longer be deleted, and we'd be right back
in the same spot we were prior to attempting the delete
method.
I love the simplicity of this example from Jetstream, but where would you or where do you use transactions in your applications? Drop me a line and let me know!