MongoDB多集合更新

4
我有一个情境,其中一个API调用需要更新两个不同的集合。如果其中一个更新失败,我需要回滚第一个更新。我如何确保两个操作都成功完成或全部失败?为了更好地理解情况,在express框架中使用MongoJS。

问题模型

{
    _id: ObjectId(),
    title: String,
    description: String,
    accepted: String,
    // Some other fields
}

答案模型

{
    _id: ObjectId(),
    qid: String, //ObjectId of question its linked to
    body: String,
    accepted: boolean,
    // Some other fields
}
方法一: 首先,从请求中获取与id对应的答案。将其标记为已接受并获取qid。将answer id插入到相应的qid对应的问题文档中。如果第二个操作失败,则恢复第一个操作。但是如果数据库连接丢失,则无法执行此操作。 方法二: 首先,获取与qid对应的问题。使用answer id更新accepted字段,然后获取对应的答案并将其标记为已接受。
然后,有一种情况是如果有一个答案被接受了,我们需要将所有其他答案都设为未接受。这是第三个操作。此外,它是一个切换操作,因此如果已经被接受,我们需要执行反向操作。
我感觉有一种更干净、更安全的处理这种情况的方式。

我有类似的要求。你找到解决方案了吗? - Jag99
从@Robb Sadler的评论中得知:从版本4开始,可以进行事务更新:docs.mongodb.com/manual/core/transactions - Nil
1个回答

1
MongoDB 没有进行多文档事务的方法。因此,没有一种清洁的方式可以执行这样的回滚。必须在应用程序中实现。MongoDB文档建议使用两阶段提交模式来实现类似事务的语义。您可以使用此方法实现回滚,但可能会很麻烦。
另一种选择是重新考虑文档架构。您能否将answer文档嵌入到question文档中?使用嵌入式文档将更好地利用Mongo的功能,而不是尝试实现事务。MongoDB具有单个文档的原子写入功能,因此,如果更新嵌入式文档时出现错误,整个操作可以回滚。

嵌套将会出现问题。它将是一个答案数组,随后将有一个回复数组。那么对回复进行更新将变得不可能。 - Nil
嗯...你是否希望同时更新回复和答案/问题,就像答案和问题一样?如果不是,也许把回复放在一个单独的集合中,在答案中只有回复 _id 的数组可能会起作用。 - tfogo
1
从版本4开始,可以进行事务更新:https://docs.mongodb.com/manual/core/transactions/ - Robb Sadler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接