【问题标题】:Atomic multiple operations in MongooseMongoose 中的原子多重操作
【发布时间】:2020-12-17 23:56:09
【问题描述】:

考虑一个架构:

var userSchema = mongoose.Schema({
...
followers: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }]
...
}

当userA 跟随userB 时,userB 将被推入userA.following,userA 将被推入userB.followers。这两个操作都需要.save()。

有什么好的方法(也许是概念性的)来确保如果.save() 中的任何一个失败,两个文档都不会受到影响?

【问题讨论】:

  • 可以不维护followers 列表吗?绝对有必要吗?您可以通过查询其他用户的following 字段来获取followers。如果您可以删除它,那将是一个单一的原子操作。
  • 感谢您的评论。我只是举了一个可能需要原子性的例子。举一个更一般的例子,请考虑 mongoose docs 上的 Story-Author 参考示例。如果我创建了 Story,但在作者的文档中添加 ref 时出现问题怎么办?
  • @BatScream 有趣的阅读。我认为它提供了我正在寻找的概念框架。谢谢。如何在 Node.js-Mongoose 中实现这一点并不直观,但我有一些值得反思的地方。就像评论一样,我对 Nodejs 社区中很少讨论原子性-隔离-一致性这一事实感到有些惊讶。是我的看法还是我遗漏了什么?
  • 如果我们按照@BatScream 的建议通过查询following 字段,我担心它会增加太多的查找时间,因为某个userB 埋在不同用户的数组中,我可以为它牺牲一些空间。

标签: node.js mongoose atomic


【解决方案1】:

结果我按照@BatScream 在第一条评论中的建议做了。我重新组织了我的数据架构并删除了列表followers。

在阅读了很多关于该主题的内容后,我得出的结论是,在 mongoDB/Mongoose.js 中跨多个文档进行事务处理虽然可行,但可能不是最聪明、最安全的做法。在实施两阶段提交时,回滚操作本身可能会失败。

如果需要跨多个文档的原子操作,可能 MongoDB 不是正确的工具。然而,一些数据重组/重组有时可能会使多文档事务变得不必要。

【讨论】:

    【解决方案2】:

    使用 Mongoose 的事务 API https://mongoosejs.com/docs/transactions.html 。这使您可以单独执行多个查询,并在其中任何一个失败时撤消所有查询

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多