我们正在使用CQRS创建系统。我们的预测在mongodb中。我们正面临一些案件。我们有一个事件说OrderCreated。我们需要产生一个顺序order_no,例如#3,#4等。我们可以使用投影并将序列保留在表中,然后称为upsert方法。并获得一个新号码。发布一个新命令:GenerateOrderNumber。现在此帖子接受的硬件故障发生之前。如果重试,我们将有另一个号码。不好如何在cqrs中解决这种用例。
答案 0 :(得分:2)
我们的预测在mongodb中<...>
现在此帖子接受的硬件故障发生之前
所描述的问题很可能与CQRS或EventSoucring本身无关,而与投影存储(上面讨论的MongoDB)有关。
您正在尝试执行没有交易保证的潜在原子操作。由于硬件故障可能是在随机时间内造成的,因此数据库应具有在当前事务中回滚失败的原子操作的功能。
最好的选择是本机MongoDB事务,该事务自4.0版本-https://docs.mongodb.com/manual/core/transactions/开始可用-您的代码将如下所示:
session.startTransaction( … );
try {
const lastNo = await eventsCollection.findOne( ... )
await eventsCollection.insertOne( …, lastNo +1 )
session.commitTransaction()
} catch (error) {
session.abortTransaction()
}
如果必须使用旧版MongoDB,则仍可以使用事务。但是,您应该手动编写事务日志,而不是使用固有运算符,并在重新连接到数据库后执行监视已损坏的事务,并通过日志手动还原它们。
答案 1 :(得分:1)
您应该通过事件执行所有操作,甚至生成序列号。 对于您的情况,我建议您使用saga:
在这种情况下,您每次在失败后要求输入新的order_no都是一样的。
如果我理解您有误,请纠正我。