簡體   English   中英

Laravel Eloquent ORM 交易

[英]Laravel Eloquent ORM Transactions

The Eloquent ORM is quite nice, though I'm wondering if there is an easy way to setup MySQL transactions using innoDB in the same fashion as PDO, or if I would have to extend the ORM to make this possible?

你可以這樣做:

DB::transaction(function() {
      //
});

閉包中的所有內容都在事務中執行。 如果發生異常,它將自動回滾。

如果您不喜歡匿名函數:

try {
    DB::connection()->pdo->beginTransaction();
    // database queries here
    DB::connection()->pdo->commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::connection()->pdo->rollBack();
}

更新 :對於laravel 4, pdo對象不再公開,因此:

try {
    DB::beginTransaction();
    // database queries here
    DB::commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::rollBack();
}

如果您想使用口才,也可以使用

這只是我的項目中的示例代碼

        /* 
         * Saving Question
         */
        $question = new Question;
        $questionCategory = new QuestionCategory;

        /*
         * Insert new record for question
         */
        $question->title = $title;
        $question->user_id = Auth::user()->user_id;
        $question->description = $description;
        $question->time_post = date('Y-m-d H:i:s');

        if(Input::has('expiredtime'))
            $question->expired_time = Input::get('expiredtime');

        $questionCategory->category_id = $category;
        $questionCategory->time_added = date('Y-m-d H:i:s');

        DB::transaction(function() use ($question, $questionCategory) {

            $question->save();

            /*
             * insert new record for question category
             */
            $questionCategory->question_id = $question->id;
            $questionCategory->save();
        });

如果您想避免閉包,並樂於使用外牆,則可以使事情保持整潔:

try {
    \DB::beginTransaction();

    $user = \Auth::user();
    $user->fill($request->all());
    $user->push();

    \DB::commit();

} catch (Throwable $e) {
    \DB::rollback();
}

如果有任何語句失敗,則提交將永遠不會執行,並且事務也不會處理。

我確定您不是要尋找封閉解決方案,請嘗試使用此解決方案以獲取更緊湊的解決方案

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

由於某種原因,在任何地方都很難找到該信息,所以我決定將其發布在這里,因為我的問題雖然與Eloquent交易有關,但確實在改變它。

讀完這個 stackoverflow的答案后,我意識到我的數據庫表正在使用MyISAM而不是InnoDB。

為了使事務能夠在Laravel上(或其他任何地方)運行,需要將表設置為使用InnoDB

為什么?

引用MySQL Transactions和Atomic Operations文檔( 此處 ):

MySQL服務器(版本3.23-max和所有版本4.0及更高版本)支持使用InnoDB和BDB事務存儲引擎的事務。 InnoDB提供完全的ACID合規性。 請參閱第14章,存儲引擎。 有關InnoDB與標准SQL在事務錯誤處理方面的區別的信息,請參見第14.2.11節“ InnoDB錯誤處理”。

MySQL Server中的其他非事務性存儲引擎(例如MyISAM)遵循稱為“原子操作”的數據完整性的另一范式。在事務方面,MyISAM表始終始終以autocommit = 1模式運行。 原子操作通常提供可比的完整性和更高的性能。

因為MySQL Server支持這兩種范例,所以您可以決定是通過原子操作的速度還是使用事務功能來最好地為應用程序提供服務。 可以按表進行選擇。

如果發生任何異常,則事務將自動回滾。

Laravel基本交易格式

    try{
    DB::beginTransaction();

    /* 
    * SQL operation one 
    * SQL operation two
    ..................     
    ..................     
    * SQL operation n */


    DB::commit();
   /* Transaction successful. */
}catch(\Exception $e){       

    DB::rollback();
    /* Transaction failed. */
}

最好和明確的方法:

DB::beginTransaction();

try {
    DB::insert(...);
    DB::insert(...);
    DB::insert(...);

    DB::commit();
    // all good
} catch (\Exception $e) {
    DB::rollback();
    // something went wrong
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM