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?
Odpowiedzi:
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();
}
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óżne
Jeś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();
});
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.
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();
}
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 ):
Serwer MySQL (wersja 3.23-max i wszystkie wersje 4.0 i nowsze) obsługuje transakcje z silnikami pamięci transakcyjnej InnoDB i BDB. InnoDB zapewnia pełną zgodność z ACID. Patrz rozdział 14, Silniki pamięci masowej. Aby uzyskać informacje na temat różnic między InnoDB a standardowym SQL w zakresie obsługi błędów transakcji, zobacz Rozdział 14.2.11, „Obsługa błędów InnoDB”.
Inne nietransakcyjne silniki pamięci masowej w MySQL Server (takie jak MyISAM) stosują inny paradygmat integralności danych, zwany „operacjami atomowymi”. Pod względem transakcyjnym tabele MyISAM skutecznie zawsze działają w trybie autocommit = 1. Operacje atomowe często oferują porównywalną integralność z wyższą wydajnością.
Ponieważ MySQL Server obsługuje oba paradygmaty, możesz zdecydować, czy Twoje aplikacje będą najlepiej obsługiwane przez szybkość niepodzielnych operacji, czy wykorzystanie funkcji transakcyjnych. Tego wyboru można dokonać na podstawie tabeli.
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. */
}