Risposte:
Puoi farlo:
DB::transaction(function() {
//
});
Tutto all'interno della chiusura viene eseguito all'interno di una transazione. Se si verifica un'eccezione, verrà eseguito il rollback automaticamente.
Discussed in more detail here
il collegamento è morto.
Se non ti piacciono le funzioni anonime:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (\PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
Aggiornamento : per laravel 4, l' pdo
oggetto non è più pubblico quindi:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (\PDOException $e) {
// Woopsy
DB::rollBack();
}
DB::beginTransaction()
& DB::commit()
& DB::rollback()
. Sarebbe un po 'più pulito.
DB::connection()->getPdo()->beginTransaction();
DB::transaction
con callback sia ancora più pulito, ma lo svantaggio è che se devi specificare diversi gestori per diverse eccezioni dovrai tornare alla tecnica try / catch
Se vuoi usare Eloquent, puoi usare anche questo
Questo è solo un esempio di codice dal mio progetto
/*
* 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
espressione al callback della transazione restituisce zero.
Se vuoi evitare chiusure e sei felice di usare le facciate, quanto segue mantiene le cose belle e pulite:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
Se qualche istruzione fallisce, il commit non verrà mai eseguito e la transazione non verrà elaborata.
Sono sicuro che non stai cercando una soluzione di chiusura, prova questa per una soluzione più compatta
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
Per qualche motivo è abbastanza difficile trovare queste informazioni ovunque, quindi ho deciso di pubblicarle qui, poiché il mio problema, sebbene correlato alle transazioni eloquenti, stava esattamente cambiando questo.
Dopo aver letto QUESTA risposta di stackoverflow, mi sono reso conto che le tabelle del mio database stavano usando MyISAM invece di InnoDB.
Affinché le transazioni funzionino su Laravel (o in qualsiasi altro posto come sembra), è necessario che le tue tabelle siano impostate per utilizzare InnoDB
Perché?
Citando Transazioni MySQL e documenti di operazioni atomiche ( qui ):
MySQL Server (versione 3.23-max e tutte le versioni 4.0 e successive) supporta le transazioni con i motori di archiviazione transazionale InnoDB e BDB. InnoDB fornisce la piena conformità ACID. Vedere il Capitolo 14, Storage Engine. Per informazioni sulle differenze di InnoDB rispetto allo standard SQL per quanto riguarda il trattamento degli errori di transazione, vedere la Sezione 14.2.11, "Gestione degli errori di InnoDB".
Gli altri motori di archiviazione non transazionali in MySQL Server (come MyISAM) seguono un paradigma diverso per l'integrità dei dati chiamato "operazioni atomiche". In termini transazionali, le tabelle MyISAM funzionano sempre efficacemente in modalità autocommit = 1. Le operazioni atomiche offrono spesso un'integrità comparabile con prestazioni più elevate.
Poiché MySQL Server supporta entrambi i paradigmi, puoi decidere se le tue applicazioni sono meglio servite dalla velocità delle operazioni atomiche o dall'uso di funzionalità transazionali. Questa scelta può essere effettuata per tavolo.
Se si verifica un'eccezione, la transazione verrà ripristinata automaticamente.
Formato di transazione 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. */
}