That was a nice joke 😐

Exception handling and Database Transaction in Laravel — Part 1

Farhat Shahir Zim
5 min readFeb 29, 2020

--

Let's say you are going to insert data into multiple tables or update a table after inserting some data into another table. In the relational database, multiple execution queries can be dependent on each other. So if we write these kinds of queries inside the database transaction and anything fails in between the transaction, the whole effect of the transaction should be reverted, as if the transaction never happened. Many unwanted unholy bugs will not occur. And life will be much easier. That's why you need to use database transactions.
Another thing, transactions are actually dependent on the underlying database engine. For example, with MySQL InnoDB you get transactions but with MyISAM you don’t. So if you’re running MySQL older than 5.5, you may need to change db engine to InnoDB for transactions

Let me tell you a story about Deadpool! He was a software engineer once. It was a shiny Monday morning and Deadpool was developing a simple wallet application. Where every user has a wallet and they can transfer money between each other’s wallet.

So let's say UserA wants to send 10$ to UserB’s wallet. What will Deadpool do in his application?

First, he will deduct 10$ from UserA’s wallet and then increase 10$ to UserB’s wallet. And then he might kill some bad guys!

Now, what if the decrement query went well but increment query went wrong? Or UserA’s wallet not found.

The answer is, his Monday motivation will die. And he will start killing both bad guys and good guys. So let’s try to keep his Monday motivation alive. Let's go with these steps for the sake of Deadpool's Monday motivation.

  1. Create a new Laravel application and generate the application secret key.
    composer create-project --prefer-dist laravel/laravel blog "5.8.*"
    php artisan key:generate

2. Create a Wallet Model and Migration.
php artisan make:model Wallet -m

3. Create WalletController with the below command.
php artisan make:controller WalletController

And create a ‘Services’ folder inside our app directory and also create WalletService.php class inside the app/Services directory.

We will write query and business logic inside of the service And we will use the controller only to call services and return API responses.

4. We will use some custom Exceptions in our WalletService.php. It’s very easy to create custom exceptions in Laravel. We have created these exceptions in our application.

Custom Exceptions:
------------------
1. CantTransferToSameWalletException.php2. ReceiverWalletNotFoundException.php3. SenderWalletNotFoundException.php4. WalletDoesNotHaveEnoughBalanceException.php

Here are the commands to create those exceptions.

php artisan make:exception CantTransferToSameWalletExceptionphp artisan make:exception ReceiverWalletNotFoundExceptionphp artisan make:exception SenderWalletNotFoundExceptionphp artisan make:exception WalletDoesNotHaveEnoughBalanceException

After that, we will have these files for our database transaction example:

Models:
-------
1. app/User.php
2. app/Wallet.php
Custom Exceptions:
------------------
3. app/Exceptions/CantTransferToSameWalletException.php
4. app/Exceptions/ReceiverWalletNotFoundException.php
5. app/Exceptions/SenderWalletNotFoundException.php
6. app/Exceptions/WalletDoesNotHaveEnoughBalanceException.php
New Migration:
--------------
7. database/migrations/2020_xx_xx_xxxxxx_create_wallets_table.php
Controller:
-----------
8. app/Http/Controllers/WalletController
Service:
--------
9. app/Services/WalletService.php
Custom Exceptions:
------------------
3. app/Exceptions/CantTransferToSameWalletException.php
4. app/Exceptions/ReceiverWalletNotFoundException.php
5. app/Exceptions/SenderWalletNotFoundException.php
6. app/Exceptions/WalletDoesNotHaveEnoughBalanceException.php
New Migration:
--------------
7. database/migrations/2020_xx_xx_xxxxxx_create_wallets_table.php
Controller:
-----------
8. app/Http/Controllers/WalletController
Service:
--------
9. app/Services/WalletService.php5. Now let’s take a look at our model, migration, service, controller, route, and custom Exception classes.

This is how our User.php should look like. Nothing much has been changed from the default User.php model. We have just added a relation with the user and the wallet. Every user has one wallet.

User.php

And this is how our Wallet.php model should look like. A relation with the wallet and the user has been added . The wallet belongs to a specific user.

Wallet.php

Now migrate this table by typing this command.
php artisan migrate

And our wallet migration file should look like this. Nothing much, just 2 columns included . The user_id and balance. That’s all.

wallet migration file

6. Now let’s create an API route to test our balance transfer method which we will create soon. Just a post route, nothing else.

Transfer balance API endpoint

Here is how our CantTransferToSameWalletException.php will look like.

CantTransferToSameWalletException.php

Here is how our ReceiverWalletNotFoundException.php will look like.

ReceiverWalletNotFoundException.php

Here is how our SenderWalletNotFoundException.php will look like.

SenderWalletNotFoundException.php

Here is how our WalletDoesNotHaveEnoughBalanceException.php will look like.

WalletDoesNotHaveEnoughBalanceException.php

Congratulations! we have created almost all the files of our application except WalletService.php and WalletController.php. These are the main things where we will find a solution to Deadpool’s Monday motivation. And with these files, we can keep Deadpool away from killing people.

But I had to divide this blog into two parts so that Deadpool can have his lunch break and have some coffee after that. Why don’t we also take a break and get a coffee? Let’s enjoy the art of Exception handing and DB transaction together at the 2nd part of this blog. Some exciting solutions and ideas are waiting for you.

Here is the link for 2nd part of this blog.

That was a nice joke too

--

--

Farhat Shahir Zim

[Software Engineer] — | Java | Python | Spring Boot | Django | C/C++ | Assembly | RISC-V | SystemC | Computer Architecture | Self taught programmer |