目前,我在从组中踢出用户时运行了很多功能。更新了多个文档,例如:
踢用户功能:
const session = await Goal.startSession();
await session.startTransaction();
const leftGoal = await Goal.findOneAndUpdate(query, update, {new : true, session})
console.log("4")
await Profile.updateOne({userID : userIDKicked}, { $unset: { goalID: undefined}}, {session})
if (leftGoal.userID == userIDKicked && leftGoal.participants.length >= 1) {
//The user who created the chat left, need to assign a new user as owner since someone left
console.log("5")
const newOwner = leftGoal.participants[0].userID;
await Goal.findOneAndUpdate({_id: goalID}, {userID: newOwner}, {session})
console.log("6")
await messaging.sendMessage(io, userIDKicked, userNameKicked + " left the chat.", goalID, 'kicked', userName, false)
}
这只是代码片段。使用 Promise.all
多次调用此代码,如下所示:
为多个用户调用 kickUser 的函数
await Promise.all(goalParticipants.map (async goal => {
await Promise.all(goal.participants.map (async participant => {
...
await kickUser.kickUser(io, goal._id, userID, participant.userName, participant.userName, null)
但是,此代码导致 MongoError: WriteConflict
。当输出到控制台时,很明显踢用户功能在切换到另一个用户之前只执行了部分,如控制台所示:
kicking out an inactive user
1
2
3
3
kicking out an inactive user
1
2
3
kicking out an inactive user
1
2
3
并且,在为每个用户打印出来之后,转到打印 5 和 6。在为其他用户运行之前,有没有办法在 Promise.all 中完整运行踢用户功能?我相信运行 kickUser 函数到一半完成然后切换线程会导致写入冲突,因为多个用户从同一个文档中被踢出,但没有一个事务完全提交/完成,因此导致写入冲突。