Coder Perfect

Eloquent ORM Transactions in Laravel

Problem

The Eloquent ORM is fairly great, but I’m wondering whether there’s a simple method to set up MySQL transactions using innoDB in the same way as PDO does, or if I’d have to extend the ORM to do so?

Asked by wesside

Solution #1

This is what you can do:

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

Everything that happens inside the Closure happens as part of a transaction. If an exception occurs, the system will automatically rollback.

Answered by Laurence

Solution #2

If you don’t like anonymous functions, try the following:

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

Update: The pdo object is no longer public in Laravel 4, so:

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

Answered by Jürgen Paul

Solution #3

You can also use this if you want to utilize Eloquent.

This is just a piece of code from one of my projects.

        /* 
         * 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();
        });

Answered by Aditya Kresna Permana

Solution #4

If you wish to avoid closures while still being able to use facades, do the following:

try {
    \DB::beginTransaction();

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

    \DB::commit();

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

If any of the statements fail, commit will never be reached, and the transaction will not be completed.

Answered by Chris

Solution #5

If a closure solution isn’t what you’re searching for, consider this for a more compact option.

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

Answered by imal hasaranga perera

Post is based on https://stackoverflow.com/questions/15105640/laravel-eloquent-orm-transactions