执行事务
Overview
在本指南中,您可以学习;了解如何使用MongoDB PHP库来执行事务。 事务允许您执行一系列仅在提交整个ACID 事务后才更改数据的操作。 如果ACID 事务中的任何操作不成功,则库会停止ACID 事务并在所有数据更改变得可见之前将其丢弃。 此功能称为原子性。
在 MongoDB 中,事务在逻辑会话中运行。 会话是要按顺序运行的一组相关读取或写入操作。 会话为一组操作启用因果一致性,并允许您在符合 ACID 的事务中运行操作,这是一个满足原子性、一致性、隔离性和持久性预期的事务。 MongoDB 保证事务操作中涉及的数据保持一致,即使操作遇到意外错误。
使用MongoDB PHP库时,您可以从 MongoDB\Client
实例创建新会话。 然后,您可以使用生成的MongoDB\Driver\Session
实例来执行事务。
警告
仅在创建Session
的Client
上运行的操作中使用 。 将Session
与不同的Client
一起使用会导致操作错误。
事务 API
在本节中,您可以学习;了解MongoDB PHP库提供的ACID 事务API。 在开始ACID 事务之前,必须在Client
实例上使用MongoDB\Client::startSession()
方法创建Session
。 然后,您可以使用以下任一 API 来执行ACID 事务:
Convenient API
MongoDB PHP库提供了一个便捷事务 API来管理ACID 事务生命周期。 通过使用MongoDB\with_transaction()
函数在ACID 事务中运行自定义回调来实施此API 。 with_transaction()
函数执行以下任务:
启动ACID 事务
通过结束ACID 事务或重试来处理错误,例如当操作返回
TransientTransactionError
提交ACID 事务
本指南的事务示例部分演示了如何使用此API来执行ACID 事务。
Core API
或者,您可以使用Session
类提供的方法更好地控制ACID 事务生命周期。 下表描述了这些方法:
方法 | 说明 |
---|---|
startTransaction() | Starts a new transaction on this session. The session
must be passed into each operation within the transaction, or
the operation will run outside of the transaction. You can set transaction options by passing an options parameter. |
commitTransaction() | Commits the active transaction for this session. This method returns an
error if there is no active transaction for the session, the
transaction was previously ended, or if there is a write conflict. |
abortTransaction() | Ends the active transaction for this session. This method returns an
error if there is no active transaction for the session or if the
transaction was committed or ended. |
事务示例
此示例定义了一个回调函数,用于修改bank
数据库集合中银行ACID 事务的数据。 该代码执行以下操作:
创建
Collection
实例以访问权限目标集合。指定帐号和账户之间转账的金额。
定义回调函数,该函数接收
Session
实例作为参数。更新客户余额以反映转账情况。
记录带有时间戳的ACID 事务收据。
如果ACID 事务提交成功,则打印一条消息。
$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; };
然后,运行以下代码以执行ACID 事务。 此代码完成以下操作:
使用
startSession()
方法从客户端创建会话。调用
with_transaction()
函数来管理ACID 事务,并将会话和回调作为参数传递。
$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 Server手册中的以下页面:
要学习;了解有关ACID compliance的更多信息,请参阅什么是数据库管理系统中的ACID属性? MongoDB网站上的文章。
要学习;了解有关插入操作的更多信息,请参阅插入文档指南。
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档:
要学习;了解有关Session
类和方法的详情,请参阅以下PHP扩展API文档: