mongoose / mongodb node.js代码:
session.commitTransaction(function(err, reply){
if(err) {
session.abortTransaction(); //Do I need this abort?
}
}
有人可以帮助我吗?
答案 0 :(得分:1)
查看mongodb的documentation有关交易及其提供的示例。
在数据库请求发生异常之后,您应该使用session.abortTransaction();
。
但是在commit
拒绝之后不需要。
说mongoose没有abortTransactions()
。所以我想这不是必需的。
// 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.hasOwnProperty("errorLabels") && 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.hasOwnProperty("errorLabels") && 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( { mode: "primary" } );
try{
runTransactionWithRetry(updateEmployeeInfo, session);
} catch (error) {
// Do something with error
} finally {
session.endSession();
}
答案 1 :(得分:0)
旧线程,但被认为可以为新手提供一些见识。
在MongoDB的Retry transaction and commit operation example上,他们在session.abortTransaction()
之后呼叫session.commitTransaction()
。
try {
await commitWithRetry(session);
} catch (error) {
await session.abortTransaction();
throw error;
}
哪个与MongoDB的abortTransaction specification冲突,该声明如下:
仅当会话在会话中时才调用abortTransaction “开始交易”或“正在进行的交易”状态。
如果此会话处于“事务已提交”状态,则驱动程序 必须引发包含错误消息“无法呼叫 调用commitTransaction后终止”。
当会话处于“开始交易”状态时,表示否 已对此交易执行操作,驱动程序不得 运行abortTransaction命令。
所以我想您的问题的答案是,您不应该。否则,您将得到错误:Cannot call abortTransaction after calling commitTransaction
。