Docs 菜单
Docs 主页
/ / /
Laravel MongoDB

事务

在此页面上

  • Overview
  • 要求和限制
  • 在回调中运行事务
  • 开始并提交事务
  • 回滚事务

在本指南中,您可以学习;了解如何使用 Laravel MongoDB在MongoDB中执行ACID 事务。 事务允许您运行一系列写入操作,这些操作仅在提交ACID 事务后更新数据。

如果ACID 事务失败,为 Laravel 集成管理MongoDB操作的MongoDB PHP库可确保MongoDB在ACID 事务中所做的所有更改变得可见之前将其丢弃。 事务的这种确保应用或丢弃ACID 事务中的所有更改的属性称为原子性

MongoDB 以原子方式对单个文档执行写入操作。 如果您需要对多个文档进行写入操作的原子性,或者需要跨多个文档执行操作的数据一致性,请在多文档事务中运行这些操作。

多文档事务符合 ACID ,因为 MongoDB 保证事务操作中的数据保持一致,即使驱动程序遇到意外错误。

要学习;了解有关MongoDB中事务的更多信息,请参阅服务器手册中的事务

本指南包含以下部分:

提示

事务学习字节

要在 MongoDB 中执行事务,必须使用以下 MongoDB 版本和拓扑:

  • MongoDB 4.0 或更高版本

  • 副本集部署或分片集群

MongoDB Server和 Laravel 集成具有以下限制:

  • 在 MongoDB 4.2及更早版本中,事务中执行的写入操作必须针对现有集合。 在 MongoDB 4.4及更高版本中,当您在事务中执行写入操作时,服务器会根据需要自动创建集合。 要了解有关此限制的更多信息,请参阅 MongoDB Server手册中的 在事务中创建集合和索引 。

  • MongoDB 不支持嵌套事务。 如果您尝试在另一个事务中启动事务,则扩展会引发 RuntimeException 。 要了解有关此限制的更多信息,请参阅 MongoDB Server手册中的 事务和会话 。

  • Laravel MongoDB不支持数据库测试特征Illuminate\Foundation\Testing\DatabaseTransactionsIlluminate\Foundation\Testing\RefreshDatabase 。 作为一种解决方法,您可以使用Illuminate\Foundation\Testing\DatabaseMigrations特征创建迁移,以便在每次测试后重置数据库。

本部分介绍如何在回调中运行事务。

使用这种运行事务的方法时,回调方法中的所有代码都作为单个事务运行。

在以下示例中,事务由写入操作组成,这些写入操作会将资金从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();
});

您可以选择将重试失败ACID 事务的最大次数作为第二个参数传递,如以下代码示例:

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

本节介绍如何启动和提交事务。

要使用这种启动和提交事务的方法,请调用DB::beginTransaction()方法启动事务。 然后,调用DB::commit()方法结束事务,这会应用在事务中执行的所有更新。

在以下示例中,第一个账户的余额转移到第二个账户,然后删除第一个账户:

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

本节介绍如何回滚事务。 回滚会恢复在该事务中执行的所有写入操作。 这意味着数据将恢复到事务之前的状态。

要执行回滚,请在提交事务之前随时调用DB::rollback()函数。

在以下示例中,事务由写入操作组成,这些写入操作将资金从Account模型表示的一个帐户转移到多个其他帐户。 如果发送者帐户资金不足,则回滚事务,并且不会更新任何模型:

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

后退

Queues