执行事务
概述
在本指南中,您可以学习如何使用MongoDB PHP库来执行事务。事务允许您执行一系列只有在整个事务提交时才改变数据的操作。如果事务中的任何操作失败,库将停止事务并丢弃所有数据更改,使它们永远不会可见。这个功能称为原子性。
在MongoDB中,事务在逻辑会话中运行。会话是一组您希望顺序运行的关联读取或写入操作。会话使一组操作的因果一致性成为可能,并允许您以符合ACID的格式运行操作,即满足原子性、一致性、隔离性和持久性期望的事务。MongoDB保证事务操作涉及的数据保持一致性,即使操作遇到意外错误。
当使用MongoDB PHP库时,您可以从MongoDB\Client
实例创建一个新的会话。然后,您可以使用生成的MongoDB\Driver\Session
实例来执行事务。
警告
仅在创建它的Client
上运行的Session
中使用。使用不同Client
的Session
会导致操作错误。
事务API
在本节中,您可以了解MongoDB PHP库提供的事务API。在开始事务之前,您必须使用您的Client
实例上的MongoDB\Client::startSession()
方法创建一个Session
。然后,您可以使用以下API之一执行事务
便捷的API
MongoDB PHP库提供了一个用于管理事务生命周期的 便捷事务API。通过使用 MongoDB\with_transaction()
函数在事务中运行自定义回调来实现此API。该 with_transaction()
函数执行以下任务:
启动事务
通过结束事务或重试(例如,当操作返回
TransientTransactionError
时)来处理错误提交事务
本指南的 事务示例 部分演示了如何使用此API执行事务。
核心API
或者,您可以通过使用 Session
类提供的方法来更细致地控制事务生命周期。以下表格描述了这些方法:
方法 | 描述 |
---|---|
startTransaction() | 在此会话上启动一个新的事务。必须在事务中的每个操作中传递会话,否则操作将在事务之外运行。 您可以通过传递一个选项参数来设置事务选项。 |
commitTransaction() | 提交此会话的当前事务。如果没有活动事务、事务之前已结束或存在写冲突,此方法将返回错误。 |
abortTransaction() | 结束此会话的当前事务。如果没有活动事务或事务已提交或结束,此方法将返回错误。 |
交易示例
此示例定义了一个回调函数,用于修改银行数据库中集合的 bank
数据库的交易数据。该代码执行以下操作
创建
Collection
实例以访问目标集合。指定要转账的账户号码和金额。
定义回调函数,该函数接收
Session
实例作为参数。更新客户的余额以反映资金转账。
记录带时间戳的交易收据。
如果交易成功提交,则打印一条消息。
$receipts = $client->bank->receipts; $checking = $client->bank->checking_accounts; $saving = $client->bank->saving_accounts; $accountId = "5678"; $transferAmount = 1000.0; $callback = function (MongoDB\Driver\Session $session) use ( $checking, $saving, $receipts, $accountId, $transferAmount ): void { $checking->updateOne( ["account_id" => $accountId], ['$inc' => ["balance" => -$transferAmount]], ["session" => $session] ); $saving->updateOne( ["account_id" => $accountId], ['$inc' => ["balance" => $transferAmount]], ["session" => $session] ); $summary = sprintf('SAVINGS +%1$u CHECKING -%1$u', $transferAmount); $receipts->insertOne( [ "account_id" => $accountId, "summary" => $summary, "timestamp" => new MongoDB\BSON\UTCDateTime(), ], ["session" => $session] ); echo "Successfully performed transaction!", PHP_EOL; echo "Summary: ", $summary, PHP_EOL; };
然后,运行以下代码以执行交易。此代码完成以下操作
使用
startSession()
方法从客户端创建会话。调用
with_transaction()
函数来管理事务,将会话和回调函数作为参数传递。
$session = $client->startSession(); try { MongoDB\with_transaction($session, $callback); } catch (MongoDB\Driver\Exception\RuntimeException $e) { echo "Caught exception: ", $e->getMessage(), PHP_EOL; }
Successfully performed transaction! Summary: SAVINGS +1000 CHECKING -1000
更多信息
要了解本指南中提到的概念,请参阅 MongoDB 服务器手册中的以下页面
要了解有关 ACID 兼容性的更多信息,请参阅 MongoDB 网站上的 数据库管理系统中的 ACID 属性是什么? 文章。
要了解有关插入操作的更多信息,请参阅插入文档 指南。
API 文档
要了解更多关于本指南中提到的方法和类型,请参阅以下 API 文档
要了解更多关于 Session
类和方法,请参阅以下 PHP 扩展 API 文档