Ahmad Mobaraki
Ahmad Mobaraki

Reputation: 8160

Laravel transaction does not rollback when none db exception happens

Here is my code:

 DB::transaction(function () use ($r, $certificate, $candidate) {

             UserCertificate::create([
                 'user_id' => $r['user_id'],
                 'certificate_id' => $certificate->id,
                 'issue_date' => Carbon::now()
              ]);

             // create badge
             $this->createCandidateBadge($candidate, $certificate);

});

An exception happens while creating the candidate badge: $this->createCandidateBadge

But when I see user_certificates table there is a certificate created! I don't want to create a certificate in DB unless a badge created successfully!

Upvotes: 1

Views: 872

Answers (2)

Omer Abdelmajeed
Omer Abdelmajeed

Reputation: 364

According to the documentation Database Transactions,

If an exception is thrown within the transaction Closure, the transaction will automatically be rolled back.

You should try to wrap your logic inside the DB::transaction by the try...catch, as follows:

DB::transaction(function () use ($r, $certificate, $candidate) {
    try {
         UserCertificate::create([
             'user_id' => $r['user_id'],
             'certificate_id' => $certificate->id,
             'issue_date' => Carbon::now()
         ]);

         // create badge
         $this->createCandidateBadge($candidate, $certificate);

    } catch (\Exception $e) {
         // Response with Error here
    }
});
// Response with success

Also check this question Laravel: Using try…catch with DB::transaction()

Enjoy :)

Upvotes: 1

Sagar Gautam
Sagar Gautam

Reputation: 9369

You can make customized transaction functionality and manual commit and rollbacks using try and catch blocks like this:

DB::beginTransaction();

try{
        UserCertificate::create([
             'user_id' => $r['user_id'],
             'certificate_id' => $certificate->id,
             'issue_date' => Carbon::now()
          ]);

         // create badge
         $this->createCandidateBadge($candidate, $certificate);

         DB::commit();

}catch (\Exception $e){
    DB::rollBack();
}

In case of exception of any type, it will be catched and then all db operations will be rollbacked. In case of no exception data will be saved.

Upvotes: 2

Related Questions