“文档” 菜单
文档首页
/
MongoDB Manual
/ / / /

Session.abortTransaction()

在此页面上

  • 定义
  • 行为
  • 例子
Session.abortTransaction()

终止多文档事务,并回滚事务中操作所做的任何数据更改。也就是说,事务结束时不保存事务中操作所做的任何更改。

多文档事务适用于分片集群和副本集。

Session.abortTransaction() 不返回值。

重要

mongosh 方法

本页面提供 mongosh 方法的相关信息。这不是数据库命令或特定语言驱动程序(例如 Node.js)的相关文档。

有关数据库命令,请参阅 abortTransaction 命令。

如需了解 MongoDB API 驱动程序,请参阅特定语言的 MongoDB 驱动程序文档。

对于传统 mongo Shell 文档,请参阅相应 MongoDB Server 版本的文档:

mongo shell v4.4

当事务中止时,事务中通过写入进行的所有数据更改都会丢弃且变得不可见,同时事务结束。

如果以审核方式运行,中止的事务中的操作仍会被审核。

如果中止操作遇到错误,无论是否将 retryWrites 设置为 true,MongoDB 驱动程序都会重试一次中止操作。有关详细信息,请参阅事务错误处理。

考虑这样一种情况:当对 hr 数据库中的员工记录进行更改时,您希望确保 reporting 数据库中的 events 集合与 hr 更改同步。换言之,您希望确保这些写入作为单个事务完成,以便两个操作要么成功,要么失败。

hr 数据库中的 employees 集合包含以下文档:

{ "_id" : ObjectId("5af0776263426f87dd69319a"), "employee" : 3, "name" : { "title" : "Mr.", "name" : "Iba Ochs" }, "status" : "Active", "department" : "ABC" }
{ "_id" : ObjectId("5af0776263426f87dd693198"), "employee" : 1, "name" : { "title" : "Miss", "name" : "Ann Thrope" }, "status" : "Active", "department" : "ABC" }
{ "_id" : ObjectId("5af0776263426f87dd693199"), "employee" : 2, "name" : { "title" : "Mrs.", "name" : "Eppie Delta" }, "status" : "Active", "department" : "XYZ" }

employees 集合具有针对 employee 字段的唯一复合索引:

db.employees.createIndex( { employee: 1 }, { unique: true } )

reporting 数据库中的 events 集合包含以下文档:

{ "_id" : ObjectId("5af07daa051d92f02462644a"), "employee" : 1, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }
{ "_id" : ObjectId("5af07daa051d92f02462644b"), "employee" : 2, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "XYZ", "old" : null } }
{ "_id" : ObjectId("5af07daa051d92f02462644c"), "employee" : 3, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }

以下示例打开一个事务,尝试将记录添加到 events 集合并将文档添加到 employees 集合。如果操作在操作或提交事务时遇到错误,会话将中止事务。

// Runs the txnFunc and retries if TransientTransactionError encountered
function runTransactionWithRetry(txnFunc, session) {
while (true) {
try {
txnFunc(session); // performs transaction
break;
} catch (error) {
// If transient error, retry the whole transaction
if (error?.errorLabels?.includes("TransientTransactionError")) {
print("TransientTransactionError, retrying transaction ...");
continue;
} else {
throw error;
}
}
}
}
// Retries commit if UnknownTransactionCommitResult encountered
function commitWithRetry(session) {
while (true) {
try {
session.commitTransaction(); // Uses write concern set at transaction start.
print("Transaction committed.");
break;
} catch (error) {
// Can retry commit
if (error?.errorLabels?.includes("UnknownTransactionCommitResult") ) {
print("UnknownTransactionCommitResult, retrying commit operation ...");
continue;
} else {
print("Error during commit ...");
throw error;
}
}
}
}
// Performs inserts and count in a transaction
function updateEmployeeInfo(session) {
employeesCollection = session.getDatabase("hr").employees;
eventsCollection = session.getDatabase("reporting").events;
// Start a transaction for the session that uses:
// - read concern "snapshot"
// - write concern "majority"
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
try{
eventsCollection.insertOne(
{ employee: 3, status: { new: "Active", old: null }, department: { new: "XYZ", old: null } }
);
// Count number of events for employee 3
var countDoc = eventsCollection.aggregate( [ { $match: { employee: 3 } }, { $count: "eventCounts" } ] ).next();
print( "events count (in active transaction): " + countDoc.eventCounts );
// The following operations should fail as an employee ``3`` already exist in employees collection
employeesCollection.insertOne(
{ employee: 3, name: { title: "Miss", name: "Terri Bachs" }, status: "Active", department: "XYZ" }
);
} catch (error) {
print("Caught exception during transaction, aborting.");
session.abortTransaction();
throw error;
}
commitWithRetry(session);
} // End of updateEmployeeInfo function
// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
try{
runTransactionWithRetry(updateEmployeeInfo, session);
} catch (error) {
// Do something with error
} finally {
session.endSession();
}

提示

另请参阅:

← 会话

在此页面上