Операции фреймворк Laravel красноречивый ORM для


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

7 65

7 ответов:

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

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

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

\DB::beginTransaction();

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

\DB::commit();

Если какие-либо инструкции не работают, commit никогда не попадет, и транзакция не будет обработана.

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

после прочтения этой stackoverflow ответ, я понял, что мои таблицы базы данных использовали MyISAM вместо InnoDB.

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

Почему?

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

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

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

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

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

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

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

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

    try{
    DB::beginTransaction();

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


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

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