我已经按照本文中的描述在MongoDB中实现了事务: https://forums.meteor.com/t/solved-transactions-with-mongodb-meteor-methods/48677
Utils.js
import { MongoInternals } from 'meteor/mongo';
// utility async function to wrap async raw mongo operations with a transaction
export const runTransactionAsync = async function (asyncRawMongoOperations, errorCode) {
// setup a transaction
const { client } = MongoInternals.defaultRemoteCollectionDriver().mongo;
const session = await client.startSession();
await session.startTransaction();
try {
// running the async operations
let result = await asyncRawMongoOperations(session);
await session.commitTransaction();
// transaction committed - return value to the client
return result;
} catch (err) {
await session.abortTransaction();
console.error(err.message);
// transaction aborted - report error to the client
throw new Meteor.Error(errorCode, err.message);
} finally {
session.endSession();
}
};
使用交易的示例:
Meteor.methods({
'changeLanguage': async function(poemId, newLanguageId) {
// define the operations we want to run in transaction
const asyncRawMongoOperations = async session => {
const poem = Poems.findOne({ _id: poemId });
const prevLanguage = poem.languageId;
const profile = Profiles.findOne({ userId: this.userId });
await Profiles.rawCollection().update(
{ userId: this.userId },
{
$inc: {
['countLanguages.' + prevLanguage]: -1,
['countLanguages.' + newLanguageId]: 1
},
$addToSet: { languages: newLanguageId }
},
{ session: session }
);
await Poems.rawCollection().update({
'_id': poemId,
'userId': this.userId
},
{
$set: {
languageId: newLanguageId
}
},
{ session: session }
);
return true; // will be the result in the client
};
let result = await runTransactionAsync(asyncRawMongoOperations, 'Error-01');
return result;
}
});
交易正常,但速度太慢。最多可能需要7秒钟。
MongoDB托管为MongoDB.Atlas。 MongoDB版本是4.0.12。
在这种情况下瓶颈在哪里?