115

Eloquent ORM は非常に優れていますが、PDO と同じ方法で innoDB を使用して MySQL トランザクションをセットアップする簡単な方法があるかどうか、またはこれを可能にするために ORM を拡張する必要があるかどうか疑問に思っています。

4

7 に答える 7

195

あなたはこれを行うことができます:

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

Closure内のすべては、トランザクション内で実行されます。例外が発生すると、自動的にロールバックされます。

于 2013-02-27T06:44:18.287 に答える
111

匿名関数が気に入らない場合:

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();
}
于 2013-02-28T02:47:23.090 に答える
40

Eloquent を使用する場合は、これも使用できます

これは私のプロジェクトのサンプルコードです

        /* 
         * 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();
        });
于 2014-02-18T21:19:56.650 に答える
38

クロージャーを避け、ファサードを喜んで使用したい場合は、次のようにして物事をきれいに保ちます。

try {
    \DB::beginTransaction();

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

    \DB::commit();

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

いずれかのステートメントが失敗した場合、コミットはヒットせず、トランザクションは処理されません。

于 2015-06-17T12:13:30.833 に答える
20

閉鎖ソリューションを探しているのではないと確信しています。よりコンパクトなソリューションについては、これを試してください

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

    DB::commit();
}catch(\Exception $e){
    DB::rollback();
}
于 2016-06-07T04:23:26.547 に答える
12

なんらかの理由で、この情報をどこでも見つけるのは非常に難しいため、Eloquent トランザクションに関連する私の問題がまさにこれを変更していたため、ここに投稿することにしました。

このスタックオーバーフローの回答を読んだ後、データベーステーブルが InnoDB ではなく MyISAM を使用していることに気付きました。

トランザクションが Laravel (またはその他の場所) で機能するためには、テーブルが InnoDB を使用するように設定されている必要があります。

なんで?

MySQLトランザクションとアトミック操作のドキュメントを引用する (ここ):

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 は両方のパラダイムをサポートしているため、アトミック操作の速度とトランザクション機能の使用のどちらがアプリケーションに最適かを判断できます。この選択は、テーブルごとに行うことができます。

于 2014-10-04T07:27:52.063 に答える