try transaction raw queryexception query multiple catch php laravel transactions

php - transaction - like laravel



Laravel: Usando try... catch con DB:: transaction() (3)

En el caso de que necesite ''salir'' manualmente de una transacción mediante código (ya sea mediante una excepción o simplemente comprobando un estado de error), no debería usar DB::transaction() sino que debe envolver su código en DB::beginTransaction y DB::commit / DB::rollback() :

DB::beginTransaction(); try { DB::insert(...); DB::insert(...); DB::insert(...); DB::commit(); // all good } catch (/Exception $e) { DB::rollback(); // something went wrong }

Ver los documentos de transacción .

Todos usamos DB::transaction() para múltiples consultas de inserción. Al hacerlo, ¿debería try...catch dentro de él o envolverlo? ¿Es incluso necesario incluir un try...catch cuando una transacción fallará automáticamente si algo sale mal?

Prueba de muestra try...catch una transacción:

// try...catch try { // Transaction $exception = DB::transaction(function() { // Do your SQL here }); if(is_null($exception)) { return true; } else { throw new Exception; } } catch(Exception $e) { return false; }

Lo opuesto, una DB::transaction() envolviendo un try ... catch:

// Transaction $exception = DB::transaction(function() { // try...catch try { // Do your SQL here } catch(Exception $e) { return $e; } }); return is_null($exception) ? true : false;

O simplemente una transacción sin intentar ... atrapar

// Transaction only $exception = DB::transaction(function() { // Do your SQL here }); return is_null($exception) ? true : false;


Podrías envolver la transacción en try..catch o incluso invertirla, aquí mi código de ejemplo que solía usar en laravel 5 ,, si miras en el interior de DB:transaction() en Illuminate/Database/Connection lo mismo que escribir manual transacción,

Transacción de Laravel

public function transaction(Closure $callback) { $this->beginTransaction(); try { $result = $callback($this); $this->commit(); } catch (Exception $e) { $this->rollBack(); throw $e; } catch (Throwable $e) { $this->rollBack(); throw $e; } return $result; }

para que pueda escribir su código de esta manera y manejar su excepción, como devolver el mensaje a su formulario mediante flash o redirigirlo a otra página. RECUERDE return inside closure se devuelve en transaction () así que si devuelve redirect()->back() no se redireccionará inmediatamente, porque el devuelve en la variable que maneja la transacción.

Envolver transacción

$result = DB::transaction(function () use ($request, $message) { try{ // execute query 1 // execute query 2 // .. return redirect(route(''account.article'')); } catch (/Exception $e) { return redirect()->back() ->withErrors([''error'' => $e->getMessage()); } }); // redirect the page return $result;

entonces la alternativa es lanzar la variable booleana y manejar la redirección fuera de la función de transacción o si necesita recuperar por qué la transacción falló, puede obtenerla desde $e->getMessage() dentro de la catch(Exception $e){...}


Si usa PHP7, use Throwable en catch para capturar excepciones de usuario y errores fatales.

Por ejemplo:

DB::beginTransaction(); try { DB::insert(...); DB::commit(); } catch (/Throwable $e) { DB::rollback(); throw $e; }

Si su código debe ser comparable con PHP5, use Exception y Throwable :

DB::beginTransaction(); try { DB::insert(...); DB::commit(); } catch (/Exception $e) { DB::rollback(); throw $e; } catch (/Throwable $e) { DB::rollback(); throw $e; }