php - transacciones - sql server laravel
Laravel Eloquent ORM Transactions (7)
El ORM Eloquent es bastante agradable, aunque me pregunto si existe una forma sencilla de configurar las transacciones MySQL usando innoDB de la misma manera que PDO, o si tendré que extender el ORM para que esto sea posible.
Estoy seguro de que no estás buscando una solución de cierre, prueba esto para una solución más compacta
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(/Exception $e){
DB::rollback();
}
Por alguna razón, es bastante difícil encontrar esta información en cualquier lugar, así que decidí publicarla aquí, ya que mi problema, mientras estaba relacionado con las transacciones Eloquent, estaba cambiando exactamente esto.
Después de leer THIS , me di cuenta de que las tablas de mi base de datos usaban MyISAM en lugar de InnoDB.
Para que las transacciones funcionen en Laravel (o en cualquier otro lugar como parezca), se requiere que sus tablas estén configuradas para usar InnoDB.
¿Por qué?
Citando transacciones de MySQL y documentos de operaciones atómicas ( here ):
MySQL Server (versión 3.23-max y todas las versiones 4.0 y posteriores) admite transacciones con los motores de almacenamiento transaccional InnoDB y BDB. InnoDB proporciona un cumplimiento completo con ACID. Consulte el Capítulo 14, Motores de almacenamiento. Para obtener información acerca de las diferencias de InnoDB con respecto al SQL estándar con respecto al tratamiento de errores de transacción, consulte la Sección 14.2.11, "Manejo de errores de InnoDB".
Los otros motores de almacenamiento no transaccionales en el servidor MySQL (como MyISAM) siguen un paradigma diferente para la integridad de datos llamado "operaciones atómicas". En términos transaccionales, las tablas MyISAM siempre operan de manera efectiva en el modo autocommit = 1. Las operaciones atómicas a menudo ofrecen una integridad comparable con un mayor rendimiento.
Dado que MySQL Server admite ambos paradigmas, puede decidir si la velocidad de las operaciones atómicas o el uso de las características transaccionales son los más adecuados. Esta elección se puede hacer por tabla.
Puedes hacerlo:
DB::transaction(function() {
//
});
Todo dentro del Cierre se ejecuta dentro de una transacción. Si ocurre una excepción, se revertirá automáticamente.
Si no te gustan las funciones anónimas:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (/PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
Actualización : para laravel 4, el objeto pdo
ya no es público así que:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (/PDOException $e) {
// Woopsy
DB::rollBack();
}
Si quiere evitar cierres y está feliz de usar fachadas, lo siguiente lo mantiene limpio y ordenado:
/DB::beginTransaction();
$user = /Auth::user();
$user->fill($request->all());
$user->push();
/DB::commit();
Si falla alguna de las sentencias, la confirmación nunca llegará, y la transacción no se procesará.
Si quieres usar Eloquent, también puedes usar esto
Esto es solo código de muestra de mi proyecto
/*
* 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();
});
Si se produce alguna excepción, la transacción se revertirá automáticamente.
Formato de transacción básico de Laravel
try{
DB::beginTransaction();
/*
* SQL operation one
* SQL operation two
..................
..................
* SQL operation n */
DB::commit();
/* Transaction successful. */
}catch(/Exception $e){
DB::rollback();
/* Transaction failed. */
}