laravel Model 執行事務

1.官方手冊是這樣介紹的:

想要在一個數據庫事務中運行一連串操作,可以使用DB門面的transaction方法,如果事務閉包中拋出異常,事務將會自動回滾。如果閉包執行成功,事務將會自動提交。使用transaction方法時不需要擔心手動回滾或提交:

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);
    DB::table('posts')->delete();
});

手動使用事務

如果你想要手動開始事務從而對回滾和提交有一個完整的控制,可以使用DB門面的beginTransaction方法:

DB::beginTransaction();

你可以通過rollBack方法回滾事務:

DB::rollBack();

最後,你可以通過commit方法提交事務:

DB::commit();

注意:使用DB門面的事務方法還可以用於控制查詢構建器和 Eloquent ORM 的事務。

2.具體是這樣使用的:

use Illuminate\Support\Facades\DB;

public function callRevert(Request $request){
        $data['call_id'] = intval($request->input('call_id'));
        $data['question_id'] = intval($request->input('question_id'));
        $data['call_name'] = $request->input('call_name');
        $data['revert'] = htmlspecialchars(trim($request->input('revert')));
        $list['page'] = intval($request->input('page'));
        $list['type_id'] = intval($request->input('type_id'));
        $list['status'] = intval($request->input('status'));
        $url = http_build_query($list);
        $url = action('Home\CallController@callQuestionView').'?'.$url;
        $validator = Validator::make($data, array('call_id' => 'required', 'call_name' => 'required','question_id'=>'required','revert'=>'required'));
        if($validator->fails()){
            FunctionController::error($url,'回覆不能爲空!');
        }else{
            DB::beginTransaction();
            try{
                FeedbackRevert::insert($data);
                FeedbackQuestion::where('id','=',$data['question_id'])->update(['status'=>1]);
                DB::commit();
                FunctionController::success($url,'回覆成功!');
            }catch (\Exception $e) {
                DB::rollBack();
                FunctionController::error($url,'回覆失敗!');
            }
        }
    }

注意事務回滾之後會有自增id 不會連續 比如 3,4,5, 在5回滾之後 再次插入數據會變成 3,4,6 會跳過 爲什麼呢?

如果你認爲自增ID不應該被事務化,那麼其他事務不得不等待着,檢查自增ID是被使用還是被回滾,這就導致阻塞

因爲innodb的auto_increament的計數器記錄的當前值是保存在存內 存中的,並不是存在於磁盤上,當mysql
server處於運行的時候,這個計數值只會隨着insert改增長,不會隨着delete而減少。而當mysql
server啓動時,當我們需要去查詢auto_increment計數值時,mysql便會自動執行:SELECT MAX(id) FROM 表名
FOR UPDATE;語句來獲得當前auto_increment列的最大值,然後將這個值放到auto_increment計數器中。所以就算
 Rollback MySQL的auto_increament計數器也不會作負運算

解決辦法:可以使用count()  等計數 方式 插入id  (比較麻煩)

發佈了150 篇原創文章 · 獲贊 112 · 訪問量 72萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章