node.js - 如何使用nodejs、express和mongoose在一个函数中保持两个操作的一致性

标签 node.js express mongoose consistency

最近,我用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无法回滚。

有什么解决办法吗? Spring 框架中类似于 @transaction 的东西?

请帮助我。

最佳答案

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

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

在 Mongodb 文档中,有一种模式可以解决这种情况,包括状态等,但在您的情况下,您可能不需要如此复杂的东西。它被称为Two-phase commit pattern 。看看是否有帮助。

关于node.js - 如何使用nodejs、express和mongoose在一个函数中保持两个操作的一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50940761/

相关文章:

node.js - 如何在 Node 中禁用请求的 SNI?

express - 如何将 redis 对象从 app.js 发送到 html <div>?

javascript - Mongoose 的奇怪错误

node.js - 将数组作为子文档添加到 Mongoose 模型实例

node.js - express-restify-mongoose 错误传播

javascript - 使用 NodeJS 设置 session 变量

node.js - 我无法在 ubuntu 上安装 @angular/cli

node.js - 无法在 bitbucket 管道中的 node.js 图像中执行 bash 脚本

javascript - 意外的 token ":",其中 JSON 从 Node 和 Express 返回

MongoDB $从带过滤器的数组中拉出