简体   繁体   中英

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!

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.

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM