Eloquent ORM jest całkiem fajny, chociaż zastanawiam się, czy istnieje łatwy sposób na skonfigurowanie transakcji MySQL przy użyciu innoDB w taki sam sposób jak PDO, czy też musiałbym rozszerzyć ORM, aby było to możliwe?
97
Możesz to zrobić:
DB::transaction(function() {
//
});
Wszystko wewnątrz Zamknięcia jest wykonywane w ramach transakcji. Jeśli wystąpi wyjątek, nastąpi automatyczne wycofanie.
Discussed in more detail here
link jest martwy.Jeśli nie lubisz anonimowych funkcji:
try { DB::connection()->pdo->beginTransaction(); // database queries here DB::connection()->pdo->commit(); } catch (\PDOException $e) { // Woopsy DB::connection()->pdo->rollBack(); }
Aktualizacja : W przypadku laravel 4
pdo
obiekt nie jest już publiczny, więc:try { DB::beginTransaction(); // database queries here DB::commit(); } catch (\PDOException $e) { // Woopsy DB::rollBack(); }
źródło
DB::beginTransaction()
&DB::commit()
&DB::rollback()
. To byłoby trochę czystsze.DB::connection()->getPdo()->beginTransaction();
DB::transaction
with callback jest jeszcze czystsza, ale wadą jest to, że jeśli musisz określić różneJeśli chcesz używać Eloquent, możesz również użyć tego
To tylko przykładowy kod z mojego projektu
/* * 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(); });
źródło
question->id
Wyraz w zwrotnego transakcji zwraca zero.Jeśli chcesz uniknąć zamknięć i chętnie używać fasad, następujące elementy pozwalają zachować ład i czystość:
try { \DB::beginTransaction(); $user = \Auth::user(); $user->fill($request->all()); $user->push(); \DB::commit(); } catch (Throwable $e) { \DB::rollback(); }
Jeśli jakiekolwiek instrukcje zawiodą, zatwierdzenie nigdy nie trafi, a transakcja nie zostanie przetworzona.
źródło
Jestem pewien, że nie szukasz rozwiązania do zamykania, wypróbuj to, aby uzyskać bardziej kompaktowe rozwiązanie
try{ DB::beginTransaction(); /* * Your DB code * */ DB::commit(); }catch(\Exception $e){ DB::rollback(); }
źródło
Z jakiegoś powodu dość trudno jest znaleźć te informacje w dowolnym miejscu, więc zdecydowałem się je tutaj zamieścić, ponieważ mój problem, związany z transakcjami Eloquent, dokładnie to zmieniał.
Po przeczytaniu TEGO odpowiedzi na stos, zdałem sobie sprawę, że moje tabele bazy danych używają MyISAM zamiast InnoDB.
Aby transakcje działały na Laravel (lub gdziekolwiek indziej, jak się wydaje), wymagane jest, aby twoje tabele korzystały z InnoDB
Czemu?
Cytowanie dokumentów dotyczących transakcji MySQL i Atomic Operations ( tutaj ):
źródło
Jeśli wystąpi jakikolwiek wyjątek, transakcja zostanie automatycznie wycofana.
Laravel Basic format transakcji
try{ DB::beginTransaction(); /* * SQL operation one * SQL operation two .................. .................. * SQL operation n */ DB::commit(); /* Transaction successful. */ }catch(\Exception $e){ DB::rollback(); /* Transaction failed. */ }
źródło