Docs HomeMongoDB Manual

Session.withTransaction()

On this page本页内容

Definition定义

Session.withTransaction( <function> [, <options> ] )

New in mongosh v1.1.0

Runs a specified lambda function within a transaction. If there is an error, the method retries the:在事务中运行指定的lambda函数。如果出现错误,该方法将重试:

  • commit operation, if there is a failure to commit.提交操作,如果提交失败。
  • entire transaction, if the error permits.整个事务,如果错误允许的话。
Important

mongosh Method

This page documents a mongosh method. This is not the documentation for database commands or language-specific drivers, such as Node.js.本页记录了一个mongosh方法。这不是数据库命令或特定语言驱动程序(如Node.js)的文档。

For the database command, see the commitTransaction command.有关数据库命令,请参阅commitTransaction命令。

For MongoDB API drivers, refer to the language-specific MongoDB driver documentation.有关MongoDB API驱动程序,请参阅特定语言的MongoDB驱动程序文档

For the legacy mongo shell documentation, refer to the documentation for the corresponding MongoDB Server release:对于遗留的mongoshell文档,请参阅相应MongoDB Server版本的文档:

mongo shell v4.4

The Session.withTransaction() method accepts the transaction options.Session.withTransaction()方法接受事务选项

Behavior行为

The Node.js driver has a version of Session.withTransaction() that is known as the Callback API. Node.js驱动程序有一个版本的Session.withTransaction(),称为回调APIThe Callback API also accepts an callback, however the return type for the Node.js method must be a Promise. 回调API也接受回调,但是Node.js方法的返回类型必须是Promise。The mongosh Session.withTransaction() method does not require a Promise.mongosh Session.withTransaction()方法不需要Promise。

Example实例

The following example creates the balances collection and uses a transaction to transfer money between two customers.以下示例创建balances(余额)集合,并使用事务在两个客户之间转账。

Create the balances collection:创建balances集合:

use accounts
db.balances.insertMany( [
{ customer: "Pat", balance: Decimal128( "35.88" ) },
{ customer: "Sasha", balance: Decimal128( "5.23" ) }
] )

Initialize some variables that are used in the transaction:初始化事务中使用的一些变量:

var fromAccount = "Pat"
var toAccount = "Sasha"
var transferAmount = 1

var dbName = "accounts"
var collectionName = "balances"

Start a session, then run a transaction to update the accounts:启动会话,然后运行事务以更新帐户:

var session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
session.withTransaction( async() => {

const sessionCollection = session.getDatabase(dbName).getCollection(collectionName);

// Check needed values检查所需的值
var checkFromAccount = sessionCollection.findOne(
{
"customer": fromAccount,
"balance": { $gte: transferAmount }
}
)
if( checkFromAccount === null ){
throw new Error( "Problem with sender account" )
}

var checkToAccount = sessionCollection.findOne(
{ "customer": toAccount }
)
if( checkToAccount === null ){
throw new Error( "Problem with receiver account" )
}

// Transfer the funds转移资金
sessionCollection.updateOne(
{ "customer": toAccount },
{ $inc: { "balance": transferAmount } }
)
sessionCollection.updateOne(
{ "customer": fromAccount },
{ $inc: { "balance": -1 * transferAmount } }
)

} )

The lambda function includes initial checks to validate the operation before updating the balances collection.lambda函数包括在更新balances集合之前验证操作的初始检查。

MongoDB automatically completes the transaction.MongoDB会自动完成事务。

  • If both updateOne() operations succeed, Session.withTransaction() commits the transaction when the callback returns.如果两个updateOne()操作都成功,则Session.withTransaction()会在回调返回时提交事务。
  • If an exception is thrown inside the callback, Session.withTransaction() ends the transaction and rolls back any uncommitted changes.如果回调内部引发异常,Session.withTransaction()将结束事务并回滚任何未提交的更改。
Note

By default, MongoDB ends transactions that run for more than 60 seconds. 默认情况下,MongoDB会结束运行超过60秒的事务。If you want to extend the default timeout to experiment with transactions in mongosh, see Runtime Limit.如果您想延长默认超时以在mongosh中进行事务实验,请参阅运行时限制