Docs 菜单
Docs 主页
/
MongoDB Manual
/ / / /

Session.abortTransaction()

在此页面上

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

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

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

Session.abortTransaction() 不返回值。

重要

mongosh 方法

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

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

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

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

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

如果中止操作遇到错误,无论是否将 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();
}

提示

另请参阅:

后退

会话

在此页面上