Подтвердить что ты не робот

Ларавелл Красноречивые транзакции ORM

Eloquent ORM довольно приятный, хотя мне интересно, есть ли простой способ настроить транзакции MySQL с помощью innoDB так же, как PDO, или если мне придется расширить ORM, чтобы сделать это возможным?

4b9b3361

Ответ 1

Вы можете сделать это:

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

Все внутри Closure выполняется внутри транзакции. Если произойдет исключение, он автоматически откатится.

Ответ 2

Если вам не нравятся анонимные функции:

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

Ответ 3

Если вы хотите использовать 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();
        });

Ответ 4

Если вы хотите избежать затворов и с удовольствием использовать фасады, то все будет хорошо и чисто:

try {
    \DB::beginTransaction();

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

    \DB::commit();

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

В случае сбоя каких-либо операторов фиксация никогда не будет выполнена, и транзакция не будет обработана.

Ответ 5

Я уверен, что вы не ищете решение для закрытия, попробуйте это для более компактного решения

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

Ответ 6

По какой-то причине эту информацию где-то найти довольно сложно, поэтому я решил опубликовать ее здесь, поскольку моя проблема, хотя и связанная с транзакциями Eloquent, как раз и меняла это.

Прочитав ЭТОТ ответ стекопотока, я понял, что в моих таблицах базы данных вместо InnoDB используется MyISAM.

Чтобы транзакции работали на Laravel (или где-либо еще, как кажется), необходимо, чтобы ваши таблицы были настроены на использование InnoDB

Почему?

Цитирование MySQL Транзакции и атомарные операции документы (здесь):

MySQL Server (версия 3.23-max и все версии 4.0 и выше) поддерживает транзакции с механизмами хранения транзакций InnoDB и BDB. InnoDB обеспечивает полное соответствие ACID. См. главу 14 "Системы хранения". Информацию об отличиях InnoDB от стандартного SQL в отношении обработки ошибок транзакций см. в разделе 14.2.11 "Обработка ошибок InnoDB".

Другие нетранзакционные механизмы хранения в MySQL Server (такие как MyISAM) придерживаются другой парадигмы целостности данных, называемой "атомарными операциями". В терминах транзакций таблицы MyISAM эффективно всегда работают в режиме autocommit = 1. Атомарные операции часто предлагают сопоставимую целостность с более высокой производительностью.

Поскольку MySQL Server поддерживает обе парадигмы, вы можете решить, будут ли ваши приложения лучше обслуживаться скоростью элементарных операций или использованием транзакционных функций. Этот выбор может быть сделан на основе таблицы.

Ответ 7

Если произойдет какое-либо исключение, транзакция автоматически откатится.

Laravel Основной формат транзакции

    try{
    DB::beginTransaction();

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


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

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