Overview
En esta guía, puedes aprender cómo realizar una transacción en MongoDB utilizando Laravel MongoDB. Las transacciones te permiten ejecutar una secuencia de operaciones de escritura que actualizan los datos solo después de que se haya confirmado la transacción.
Si la transacción falla, la librería MongoDB PHP, que gestiona las operaciones de MongoDB para la integración con Laravel, garantiza que MongoDB descarte todos los cambios realizados dentro de la transacción antes de que sean visibles. Esta propiedad de las transacciones que garantiza que todos los cambios dentro de una transacción se apliquen o se descarten se denomina atomicidad.
MongoDB realiza operaciones de escritura en documentos individuales de forma atómica. Si necesita atomicidad en las operaciones de escritura en varios documentos o consistencia de datos entre ellos, ejecútelas en una transacción multidocumento.
Las transacciones de múltiples documentos cumplen con ACID porque MongoDB garantiza que los datos en sus operaciones de transacción permanecen consistentes, incluso si el controlador encuentra errores inesperados.
Para obtener más información sobre las transacciones en MongoDB, consulta Transacciones en el manual del servidor.
Esta guía contiene las siguientes secciones:
Tip
Byte de aprendizaje de transacciones
Practique el uso de la integración de Laravel para realizar transacciones en el Laravel Transactions Learning Byte.
Requisitos y límites
El servidor MongoDB y la integración de Laravel tienen las siguientes limitaciones:
Las implementaciones autónomas de MongoDB no admiten transacciones. Para usar transacciones, tu implementación debe ser un set de réplicas de varios nodos o un clúster particionado.
MongoDB no admite transacciones anidadas. Si intentas iniciar una transacción dentro de otra, la extensión genera una
RuntimeExceptionPara obtener más información sobre esta limitación, consulte Transacciones y sesiones en el manual del servidor.Laravel MongoDB no admite los rasgos de prueba de bases de datos
Illuminate\Foundation\Testing\DatabaseTransactionsyIlluminate\Foundation\Testing\RefreshDatabase. Como solución temporal, puedes crear migraciones con elIlluminate\Foundation\Testing\DatabaseMigrationstrait para restablecer la base de datos después de cada prueba.Laravel MongoDB no admite la ejecución de operaciones paralelas dentro de una sola transacción.
Ejecutar una transacción en una devolución de llamada
Esta sección muestra cómo puedes ejecutar una transacción en una función de retorno.
Al utilizar este método para ejecutar una transacción, todo el código del método de devolución de llamada se ejecuta como una sola transacción.
En el siguiente ejemplo, la transacción consiste en operaciones de escritura que transfieren fondos de una cuenta bancaria, representada por el modelo Account, a otra cuenta:
DB::transaction(function () { $transferAmount = 200; $sender = Account::where('number', 223344)->first(); $sender->balance -= $transferAmount; $sender->save(); $receiver = Account::where('number', 776655)->first(); $receiver->balance += $transferAmount; $receiver->save(); });
Opcionalmente, puedes pasar el número máximo de veces para reintentar una transacción fallida como el segundo parámetro, como se muestra en el siguiente ejemplo de código:
DB::transaction(function() { // transaction code }, attempts: 5, );
Iniciar y Confirmar una Transacción
Esta sección muestra cómo iniciar y confirmar una transacción.
Para usar este método de inicio y confirmación de una transacción, llame al método DB::beginTransaction() para iniciarla. Luego, llame al método DB::commit() para finalizarla, lo que aplica todas las actualizaciones realizadas dentro de la transacción.
En el siguiente ejemplo, el saldo de la primera cuenta se pasa a la segunda cuenta, tras lo cual se borra la primera cuenta:
DB::beginTransaction(); $oldAccount = Account::where('number', 223344)->first(); $newAccount = Account::where('number', 776655)->first(); $newAccount->balance += $oldAccount->balance; $newAccount->save(); $oldAccount->delete(); DB::commit();
Revertir una transacción
Esta sección muestra cómo revertir una transacción. Un rollback revierte todas las operaciones de escritura realizadas dentro de esa transacción. Esto significa que los datos se revierten a su estado antes de la transacción.
Para realizar el rollback, llama a la función DB::rollback() en cualquier momento antes de que la transacción se confirme.
En el siguiente ejemplo, la transacción consiste en operaciones de guardar que transfieren fondos de una cuenta, representada por el modelo Account, a múltiples otras cuentas. Si la cuenta del remitente carece de fondos suficientes, la transacción se revierte y ninguno de los modelos se actualiza:
DB::beginTransaction(); $sender = Account::where('number', 223344)->first(); $receiverA = Account::where('number', 776655)->first(); $receiverB = Account::where('number', 990011)->first(); $amountA = 100; $amountB = 200; $sender->balance -= $amountA; $receiverA->balance += $amountA; $sender->balance -= $amountB; $receiverB->balance += $amountB; if ($sender->balance < 0) { // insufficient balance, roll back the transaction DB::rollback(); } else { DB::commit(); }