Відповіді:
Ви можете зробити це:
DB::transaction(function() {
//
});
Усе усередині Закриття виконується в межах транзакції. У разі виникнення винятку він автоматично відкочується.
Discussed in more detail here
посилання мертве.
Якщо вам не подобаються анонімні функції:
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();
}
DB::beginTransaction()
& DB::commit()
& DB::rollback()
. Це було б трохи чистіше.
DB::connection()->getPdo()->beginTransaction();
DB::transaction
із зворотним викликом ще чистіше, але недоліком є те, що якщо вам потрібно вказати різні обробники для різних винятків, вам доведеться повернутися, щоб спробувати / зловити техніку
Якщо ви хочете використовувати 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();
});
question->id
Вираз на зворотний виклик транзакції повертає нуль.
Якщо ви хочете уникнути перекриттів та з задоволенням користуєтесь фасадами, наступне робить речі приємними та чистими:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
Якщо будь-які оператори не вдаються, коміт ніколи не потрапить, і транзакція не оброблятиметься.
Я впевнений, що ви не шукаєте рішення закриття, спробуйте це для більш компактного рішення
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
З якоїсь причини досить важко знайти цю інформацію де-небудь, тому я вирішив розмістити її тут, оскільки моє видання, хоч і було пов’язане з красномовними транзакціями, саме змінило це.
Прочитавши ЦЮ відповідь на stackoverflow, я зрозумів, що мої таблиці бази даних використовують MyISAM замість InnoDB.
Щоб транзакції працювали на Laravel (або де-небудь ще, як здається), потрібно, щоб ваші таблиці використовували InnoDB
Чому?
Цитування документації щодо транзакцій MySQL та атомних операцій ( тут ):
Сервер MySQL (версія 3.23-max та всі версії 4.0 і вище) підтримує транзакції з механізмами зберігання транзакцій InnoDB та BDB. InnoDB забезпечує повну відповідність кислоті. Див. Розділ 14, Механізми зберігання. Інформацію про відмінності InnoDB від стандартного SQL щодо обробки помилок транзакцій див. У Розділі 14.2.11, “Обробка помилок InnoDB”.
Інші нетранзакційні механізми зберігання на MySQL Server (наприклад, MyISAM) дотримуються іншої парадигми цілісності даних, яка називається «атомні операції». З точки зору транзакцій, таблиці MyISAM ефективно завжди працюють в режимі autocommit = 1. Атомні операції часто пропонують порівнянну цілісність і високу продуктивність.
Оскільки сервер MySQL підтримує обидві парадигми, ви можете вирішити, чи найкраще ваші додатки обслуговуються швидкістю атомних операцій або використанням транзакційних функцій. Цей вибір можна зробити для кожного столу.
У разі виникнення будь-якого винятку транзакція автоматично відкочується.
Формат транзакції 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. */
}