Respostas:
Você consegue fazer isso:
DB::transaction(function() {
//
});
Tudo dentro do Closure é executado dentro de uma transação. Se ocorrer uma exceção, ele será revertido automaticamente.
Discussed in more detail here
link está morto.
Se você não gosta de funções anônimas:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (\PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
Atualização : Para laravel 4, o pdo
objeto não é mais público, então:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (\PDOException $e) {
// Woopsy
DB::rollBack();
}
DB::beginTransaction()
& DB::commit()
& DB::rollback()
. Isso seria um pouco mais limpo.
DB::connection()->getPdo()->beginTransaction();
DB::transaction
callback com é ainda mais limpo, mas a desvantagem é que se você precisar especificar diferentes manipuladores para diferentes exceções, você terá que voltar para a técnica de tentativa / captura
Se você quiser usar o Eloquent, também pode usar este
Este é apenas um exemplo de código do meu projeto
/*
* 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
expressão no retorno de chamada da transação retorna zero.
Se você quiser evitar fechamentos e ficar feliz em usar fachadas, o seguinte mantém as coisas boas e limpas:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
Se alguma instrução falhar, o commit nunca ocorrerá e a transação não será processada.
Tenho certeza de que você não está procurando uma solução de fechamento, tente uma solução mais compacta
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
Por algum motivo, é muito difícil encontrar essas informações em qualquer lugar, então decidi postá-las aqui, pois meu problema, embora relacionado às transações do Eloquent, estava exatamente mudando isso.
Depois de ler ESTA resposta stackoverflow, percebi que minhas tabelas de banco de dados estavam usando MyISAM em vez de InnoDB.
Para que as transações funcionem no Laravel (ou em qualquer outro lugar que pareça), é necessário que suas tabelas sejam configuradas para usar InnoDB
Por quê?
Citando documentos do MySQL Transactions and Atomic Operations ( aqui ):
MySQL Server (versão 3.23-max e todas as versões 4.0 e superiores) oferece suporte a transações com os mecanismos de armazenamento transacional InnoDB e BDB. InnoDB fornece conformidade total com ACID. Consulte o Capítulo 14, Mecanismos de armazenamento. Para obter informações sobre as diferenças entre o InnoDB e o SQL padrão em relação ao tratamento de erros de transação, consulte a Seção 14.2.11, “Tratamento de erros do InnoDB”.
Os outros mecanismos de armazenamento não transacional no MySQL Server (como MyISAM) seguem um paradigma diferente para integridade de dados, chamado de “operações atômicas”. Em termos transacionais, as tabelas MyISAM sempre operam efetivamente no modo autocommit = 1. As operações atômicas geralmente oferecem integridade comparável com desempenho superior.
Como o MySQL Server oferece suporte a ambos os paradigmas, você pode decidir se seus aplicativos são mais bem atendidos pela velocidade das operações atômicas ou pelo uso de recursos transacionais. Essa escolha pode ser feita por mesa.
Se ocorrer alguma exceção, a transação será revertida automaticamente.
Formato de transação do 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. */
}