Docs Menu
Docs Home
/ / /
Laravel MongoDB

Transactions

On this page

  • Overview
  • Requirements and Limitations
  • Run a Transaction in a Callback
  • Begin and Commit a Transaction
  • Roll Back a Transaction

In this guide, you can learn how to perform a transaction in MongoDB by using Laravel MongoDB. Transactions let you run a sequence of write operations that update the data only after the transaction is committed.

If the transaction fails, the MongoDB PHP Library that manages MongoDB operations for the Laravel Integration ensures that MongoDB discards all the changes made within the transaction before they become visible. This property of transactions that ensures that all changes within a transaction are either applied or discarded is called atomicity.

MongoDB performs write operations on single documents atomically. If you need atomicity in write operations on multiple documents or data consistency across multiple documents for your operations, run them in a multi-document transaction.

Multi-document transactions are ACID compliant because MongoDB guarantees that the data in your transaction operations remains consistent, even if the driver encounters unexpected errors.

To learn more about transactions in MongoDB, see Transactions in the Server manual.

This guide contains the following sections:

Tip

Transactions Learning Byte

Practice using the Laravel Integration to perform transactions in the Laravel Transactions Learning Byte.

To perform transactions in MongoDB, you must use the following MongoDB version and topology:

  • MongoDB version 4.0 or later

  • A replica set deployment or sharded cluster

MongoDB Server and the Laravel Integration have the following limitations:

  • In MongoDB versions 4.2 and earlier, write operations performed within a transaction must be on existing collections. In MongoDB versions 4.4 and later, the server automatically creates collections as necessary when you perform write operations in a transaction. To learn more about this limitation, see Create Collections and Indexes in a Transaction in the Server manual.

  • MongoDB does not support nested transactions. If you attempt to start a transaction within another one, the extension raises a RuntimeException. To learn more about this limitation, see Transactions and Sessions in the Server manual.

  • Laravel MongoDB does not support the database testing traits Illuminate\Foundation\Testing\DatabaseTransactions and Illuminate\Foundation\Testing\RefreshDatabase. As a workaround, you can create migrations with the Illuminate\Foundation\Testing\DatabaseMigrations trait to reset the database after each test.

This section shows how you can run a transaction in a callback.

When using this method of running a transaction, all the code in the callback method runs as a single transaction.

In the following example, the transaction consists of write operations that transfer the funds from a bank account, represented by the Account model, to another account:

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();
});

You can optionally pass the maximum number of times to retry a failed transaction as the second parameter, as shown in the following code example:

DB::transaction(function() {
// transaction code
},
attempts: 5,
);

This section shows how to start and commit a transaction.

To use this method of starting and committing a transaction, call the DB::beginTransaction() method to start the transaction. Then, call the DB::commit() method to end the transaction, which applies all the updates performed within the transaction.

In the following example, the balance from the first account is moved to the second account, after which the first account is deleted:

DB::beginTransaction();
$oldAccount = Account::where('number', 223344)->first();
$newAccount = Account::where('number', 776655)->first();
$newAccount->balance += $oldAccount->balance;
$newAccount->save();
$oldAccount->delete();
DB::commit();

This section shows how to roll back a transaction. A rollback reverts all the write operations performed within that transaction. This means that the data is reverted to its state before the transaction.

To perform the rollback, call the DB::rollback() function anytime before the transaction is committed.

In the following example, the transaction consists of write operations that transfer funds from one account, represented by the Account model, to multiple other accounts. If the sender account has insufficient funds, the transaction is rolled back, and none of the models are updated:

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();
}

Back

Queues