仔细阅读在线文档后,我仍然对 MongoDB 中的两阶段提交有很多疑问。
在从故障场景中恢复部分中,为什么只有两类故障?在我看来,这些步骤中的任何一个都可能发生失败,所以这里应该有两个以上的类。例如,如果(在将事务应用到两个帐户部分)更新帐户 A 后数据库服务器出现故障怎么办。这意味着账户 A 损失了一些钱,而账户 B 没有发生任何事情。我们会有不一致的交易吗?
仔细阅读在线文档后,我仍然对 MongoDB 中的两阶段提交有很多疑问。
在从故障场景中恢复部分中,为什么只有两类故障?在我看来,这些步骤中的任何一个都可能发生失败,所以这里应该有两个以上的类。例如,如果(在将事务应用到两个帐户部分)更新帐户 A 后数据库服务器出现故障怎么办。这意味着账户 A 损失了一些钱,而账户 B 没有发生任何事情。我们会有不一致的交易吗?
当应用程序或数据库在将事务应用到 A 和将事务应用到 B 之间突然崩溃时,全局事务集合中仍然会有一个事务 with state:"pending"
。您在崩溃后运行的恢复脚本应该注意到这一点,检查这两个帐户,并查看其中一个帐户中存在待处理事务,但另一个帐户中没有。它现在知道回滚事务或尝试完成事务所需知道的一切。
是的,编写一个如此智能的恢复脚本并不容易。但是在不是为他们设计的数据库系统中的事务总是很难的。有时,您可以通过设计文档来解决在 MongoDB 中需要事务的问题,即需要一起更新的字段始终位于同一个文档中,但并不总是有一种明智的方法来做到这一点。当您的用例绝对需要事务时,请保护您的理智并使用关系数据库。
在我看来,这些步骤中的任何一个都可能发生失败,所以这里应该有两个以上的类。
这里要记住的关键是文档不是关于两阶段提交的权威指南,实际上两阶段提交在 MongoDB 中技术上是不可能的,如果你想执行它们,我强烈建议你获得 ACID 技术。
您必须记住,由于不在服务器本身内,您无法应对某些失败情况。相反,两阶段提交的整个存在只是客户端,因此与 TTL 监控相比,它非常脆弱。
更新帐户 A 后,数据库服务器出现故障。这意味着账户 A 损失了一些钱,而账户 B 没有发生任何事情。我们会有不一致的交易吗?
为了支持 Philipps 的回答,在这种情况下,账户 A 和 B 之间的原始交易仍将处于待处理状态,只有在账户 B 更新后才会将其移至完成/完成。
这意味着事务在完成之前不能被标记为已完成。
与其将 MongoDB 用于并非真正为它设计的场景,我建议使用专为您的场景设计的东西。
在线文档可能并不完美。实际上,您确实需要回滚 A 和 B 上的操作