關(guān)于 tp5 事務(wù)操作總結(jié)

前提:

使用事務(wù)處理的話,需要數(shù)據(jù)庫(kù)引擎支持事務(wù)處理。比如 MySQL 的 MyISAM 不支持事務(wù)處理,需要使用 InnoDB 引擎。

事務(wù)操作

使用場(chǎng)景

    Db::startTrans();
    try{
        Db::name('users')->insert(array('name'=>'mike','age'=>28));
         Db::name('products')->where('id','=',1)->update(array('status'=>2));       
        Db::commit();
        return json_return("事務(wù)操作成功");      // json_return() 為封裝返回json數(shù)據(jù)的方法
    }catch (\Exception $e){
        Db::rollback();
        return json_return($e->getMessage());      // json_return() 為封裝返回json數(shù)據(jù)的方法
    }

針對(duì)事務(wù)操作,我們首先需要了解事務(wù)的意義:這里不詳述了,不清楚的朋友可參考 MySQL事務(wù) 進(jìn)行了解。

常見(jiàn)問(wèn)題

  • 問(wèn)題1:如上代碼中如果第一條新增語(yǔ)句 返回 true , 第二條更新語(yǔ)句返回 false ,那這個(gè)事務(wù)還是會(huì) commit 的,而不是我們預(yù)期的rellback,這是為什么?

     如果想讓兩條 sql 真正按照自己的意愿都 "執(zhí)行成功(都返回 true 時(shí))" 時(shí)再提交事務(wù),那需要這樣寫(xiě):
      Db::startTrans();
      try{
          $res1 = Db::name('users')->insert(array('name'=>'mike','age'=>28));
          $res2= Db::name('products')->where('id','=',1)->update(array('status'=>2));       
      }catch (\Exception $e){
          Db::rollback();
      } 
    
      if($re1 && $re2){
          Db::commit();
          return json_return("事務(wù)操作成功");      // json_return() 為封裝返回json數(shù)據(jù)的方法
       }else{
          Db::rollback();
          return json_return($e->getMessage());      // json_return() 為封裝返回json數(shù)據(jù)的方法
       }
    
     【延伸】 事務(wù)回滾的條件指的是 sql  語(yǔ)法報(bào)錯(cuò),而不是增加、刪除、更改 sql 時(shí)的影響行數(shù)為0
    
  • 問(wèn)題2: 在事務(wù)中,使用了tp5 的函數(shù) $this->success(),即使事務(wù)里面的 sql 語(yǔ)句都成功了,但還是走了rollback,為什么?

           Db::startTrans();
           try{
               Db::name('users')->insert(array('name'=>'mike','age'=>28));
               Db::name('products')->where('id','=',1)->update(array('status'=>2));       
               Db::commit();
               $this->success("事務(wù)操作成功");   
           }catch (\Exception $e){
               Db::rollback();
               $this->error($e->getMessage());
           }
    
           是因?yàn)?this->success() 這個(gè)函數(shù)的源碼其實(shí)也是會(huì)拋出異常(這里可查看$this->success() 的方法),
           解決辦法:
             將
                catch (\Exception $exception)
             改成
                catch (\think\Exception\DbException $exception)   // 僅catch sql 異常
             即可。
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容