Definition定义
Session.abortTransaction()Terminates the multi-document transaction and rolls back any data changes made by the operations within the transaction. That is, the transaction ends without saving any of the changes made by the operations in the transaction.终止多文档事务,并回滚事务中操作所做的任何数据更改。也就是说,事务结束时不会保存事务中操作所做的任何更改。Multi-document transactions are available for both sharded clusters and replica sets.多文档事务可用于分片集群和副本集。Session.abortTransaction()does not return a value.不返回值。Important
mongosh
Method方法This page documents a本页记录了一种mongoshmethod. 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有关数据库命令,请参阅abortTransactioncommand.abortTransaction命令。For MongoDB API drivers, refer to the language-specific MongoDB driver documentation.有关MongoDB API驱动程序,请参阅特定语言的MongoDB驱动程序文档。
Compatibility兼容性
This method is available in deployments hosted in the following environments:此方法在以下环境中托管的部署中可用:
- MongoDB Atlas
: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务
Note
This command is supported in all MongoDB Atlas clusters. 所有MongoDB Atlas集群都支持此命令。For information on Atlas support for all commands, see Unsupported Commands.有关Atlas支持所有命令的信息,请参阅不支持的命令。
- MongoDB Enterprise
: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本 - MongoDB Community
: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本
Behavior行为
Atomicity原子性
When a transaction aborts, all data changes made by the writes in the transaction are discarded without ever becoming visible and the transaction ends.当事务中止时,事务中写入所做的所有数据更改都将被丢弃,不再可见,事务结束。
Security安全
If running with auditing, operations in an aborted transaction are still audited.如果使用审核运行,则中止事务中的操作仍将被审核。
Retryable可重试
If the abort operation encounters an error, MongoDB drivers retry the abort operation a single time regardless of whether 如果中止操作遇到错误,MongoDB驱动程序将重试中止操作一次,而不管retryWrites is set to true. retryWrites是否设置为true。For more information, see Transaction Error Handling.有关更多信息,请参阅事务错误处理。
Example示例
Consider a scenario where as changes are made to an employee's record in the 考虑一种情况,当对hr database, you want to ensure that the events collection in the reporting database are in sync with the hr changes and vice versa. hr数据库中的员工记录进行更改时,您希望确保报告数据库中的事件集合与人力资源更改同步,反之亦然。That is, you want to ensure that these writes are done as a single transaction, such that either both operations succeed or fail.也就是说,您希望确保这些写入作为单个事务完成,以便两个操作都成功或失败。
The employees collection in the hr database has the following documents: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" }
The employees collection has a unique index on the employee field:employees集合在employee字段上有一个唯一的索引:
db.employees.createIndex( { employee: 1 }, { unique: true } )
The events collection in the reporting database has the following documents: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 } }
The following example opens a transaction, attempts to add a record to the 以下示例打开一个事务,尝试将记录添加到events collection and add a document to the employees collection. If the operation encounters an error in either operations or in committing the transaction, the session aborts the transaction.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();
}