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. */ }