MongoDB多个集合更新
问题描述:
我有一个API调用需要更新两个单独集合的场景。如果一次更新失败,我需要恢复第一次更新。我如何确保两项操作都能成功完成,否则无法完成。为了澄清,这里是情况。在express框架中使用MongoJS。MongoDB多个集合更新
问题型号
{
_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
}
方法1: 首先要将对应于请求中的id
答案。将其标记为已接受并获得qid
。将answer id
插入对应于qid
的问题文档中。如果第二次操作失败,则恢复第一次操作。但是,如果数据库连接丢失,则无法执行。
方法2 首先得到相应的问题qid
。用answer id
更新accepted
字段,然后获取与其对应的答案并将其标记为已接受。
然后有这样的情况,如果一个答案被接受,我们需要使所有其他答案不被接受。这是一个第三个操作。此外,它是一种切换操作,所以如果它已被接受,我们需要做相反的事情。
我有一种感觉,有一种更清洁和更安全的方式来处理这种情况。
答
MongoDB does not have a way of doing multi-document transactions。所以没有像这样做回滚的干净方式。它必须在应用程序中执行。 MongoDB文档建议使用two-phase commit模式来创建类似事务的语义。你可以使用这个来实现回滚,但这可能非常麻烦。
另一种方法是重新考虑文档模式。你可以在你的question
文件中嵌入你的answer
文件吗?使用嵌入式文档将更好地利用Mongo的功能,而不是试图执行事务。 MongoDB对单个文档进行原子写入,因此如果在更新嵌入式文档时出现错误,则可以回滚整个操作。
嵌入将有问题。这将是一系列答案,随后将会有一系列答复。然后执行回复更新将变得不可能。 – Nil
嗯......你想要在答案和问题的同时更新答复和答案/问题吗?如果没有,可能在一个单独的集合中有回复,并且在答案中只有一个'_id'的回复可能有效? – tfogo