Overview
En esta guía, aprenderá a realizar una transacción en MongoDB usando Laravel MongoDB. Las transacciones permiten ejecutar una secuencia de operaciones de escritura que actualizan los datos solo después de confirmar la transacción.
Si la transacción falla, la biblioteca PHP de MongoDB, que gestiona las operaciones de MongoDB para la integración con Laravel, garantiza que MongoDB descarte todos los cambios realizados en 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 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, consulte 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 Laravel Transactions Learning Byte.
Requisitos y limitaciones
El servidor MongoDB y la integración de Laravel tienen las siguientes limitaciones:
Las implementaciones independientes de MongoDB no admiten transacciones. Para usarlas, su implementación debe ser un conjunto de réplicas de varios nodos o un clúster fragmentado.
MongoDB no admite transacciones anidadas. Si intenta iniciar una transacción dentro de otra, la extensión genera un error.
RuntimeExceptionPara obtener más información sobre esta limitación, consulte Transacciones y sesiones en el manual del servidor.Laravel MongoDB no admite los traits
Illuminate\Foundation\Testing\DatabaseTransactionsyIlluminate\Foundation\Testing\RefreshDatabasepara pruebas de bases de datos. Como solución alternativa, puede crear migraciones con el traitIlluminate\Foundation\Testing\DatabaseMigrationspara 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 puede ejecutar una transacción en una devolución de llamada.
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 consta de operaciones de escritura que transfieren los 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, puede pasar el número máximo de veces que se debe reintentar una transacción fallida como 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 mueve a la segunda cuenta, después de lo cual se elimina 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 la reversión, llame a la función DB::rollback() en cualquier momento antes de que se confirme la transacción.
En el siguiente ejemplo, la transacción consiste en operaciones de escritura que transfieren fondos de una cuenta, representada por el modelo Account, a varias cuentas. Si la cuenta emisora no tiene fondos suficientes, la transacción se revierte y no se actualiza ninguno de los modelos.
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(); }