首页 > 解决方案 > 如何使用nodejs,express和mongoose在一个函数中保持两个操作的一致性

问题描述

最近,我用express和mongoose编写了一个nodejs应用程序。

当我在一个函数中更新两个集合时,问题就出现了。

代码段如下所示。

exports.doVote = async (req, res) => {
  // some codes...

  // Operation 1
  const voteNumInfo = await VoteNumInfo.findOneAndUpdate({ activityId, vodId },
    { vodId, vodName, activityId, categoryId, categoryName, $inc: { voteNum: 1, showNum: 1 } },
    { new: true, upsert: true, setDefaultsOnInsert: true });

  // Operation 2
  await VoteInfo.create({ vodId, vodName, activityId, categoryId, voteDate, stbId, ptag });

  // some codes...
}

其中VoteNumInfo是投票统计VoteInfo模型, 是投票记录模型。

当操作 2 出错时,操作 1 无法回滚。

有什么解决办法吗?类似于@transactionSpring Framework 中的东西?

请帮我。

标签: node.jsexpressmongooseconsistency

解决方案


在 MongoDB 中,所有要写入的操作在文档级别都是原子的。这意味着即使一个写操作影响到多个文档,每个文档都是原子的。因此,mongodb 本身不提供交易方式(更多信息在 doc here中)

解决您的问题的简单方法是捕获异常,如果第一个查询已成功执行而第二个未成功执行,您可以执行一个查询以撤消您之前执行的操作(使用 $dec)

在 Mongodb 文档中,有一种模式可以解决这种情况,包括状态等,但在您的情况下,您可能不需要任何如此复杂的东西。它被称为两阶段提交模式。看看它是否有帮助。


推荐阅读