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

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

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

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

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

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

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

Если вы хотите использовать 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('Ymd H:i:s'); if(Input::has('expiredtime')) $question->expired_time = Input::get('expiredtime'); $questionCategory->category_id = $category; $questionCategory->time_added = date('Ymd 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(); 

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

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

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

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

Зачем?

Цитирование транзакций MySQL Transactions и Atomic Operations ( здесь ):

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 поддерживает обе парадигмы, вы можете решить, лучше ли ваши приложения обслуживать скорость атомных операций или использование транзакционных функций. Этот выбор можно сделать на основе таблицы.

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

  try{ DB::beginTransaction(); /* * Your DB code * */ DB::commit(); }catch(\Exception $e){ DB::rollback(); } 

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

Формат транзакции Laravel Basic

  try{ DB::beginTransaction(); /* * SQL operation one * SQL operation two .................. .................. * SQL operation n */ DB::commit(); /* Transaction successful. */ }catch(\Exception $e){ DB::rollback(); /* Transaction failed. */ }