Laravel Красноречивые транзакции ORM
Красноречивый ORM довольно хорош, хотя мне интересно, есть ли простой способ настроить транзакции MySQL с использованием InnoDB таким же образом, как PDO, или мне придется расширить ORM, чтобы сделать это возможным?
7 answers
Вы можете сделать это:
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();
Если какие-либо инструкции завершатся неудачно, фиксация никогда не произойдет, и транзакция не будет обработана.
По какой-то причине довольно сложно найти эту информацию где-либо, поэтому я решил опубликовать ее здесь, так как моя проблема, связанная с красноречивыми транзакциями, как раз и меняла это.
Прочитав ЭТОТ ответ на стековый поток, я понял, что в моих таблицах базы данных используется MyISAM вместо InnoDB.
Чтобы транзакции работали в Laravel (или где-либо еще, как кажется), необходимо, чтобы ваши таблицы были настроены на использование InnoDB (ИНН)
Почему?
Цитирование MySQL Транзакции и атомарные операции документы ( здесь):
Сервер MySQL (версия 3.23-max и все версии 4.0 и выше) поддерживает транзакции с механизмами транзакционного хранения InnoDB и BDB. InnoDB обеспечивает полное соответствие требованиям ACID. См. Главу 14, Механизмы хранения. Для получения информации об отличиях InnoDB от стандартного SQL в отношении обработки ошибок транзакций см. Раздел 14.2.11, "Ошибка InnoDB Обработка".
Другие нетранзакционные механизмы хранения данных на сервере MySQL (такие как MyISAM) следуют другой парадигме целостности данных, называемой "атомарными операциями". В транзакционных терминах таблицы MyISAM эффективно всегда работают в режиме автоматической фиксации = 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. */
}