我想将域事件保存为 DocumentDB 中的文档,然后在 Azure Service Bus(ASB)上发布该事件,以便其他服务进行提取。我想在一个事务中执行这两个操作,以便在其中一个失败时,另一个事务会自动回滚。
ASB为处理程序中的传入和传出(下游)消息提供事务支持,即,如果处理程序失败,则不会发送这些消息,并且不会从总线中删除处理程序中接收的原始消息。但是在同一个处理程序中保存的任何数据怎么样,比如在我的情况下将事件存储在DocumentDB中?如何将其包含在该交易中?
答案 0 :(得分:1)
三个想法:
使整个交易的一方或另一方是幂等的,先做另一方,如果它通过尝试/重试,直到另一方通过。幂等性意味着您可以多次重做特定事务,效果将与您执行一次相同。所以,继续重试直到它通过。这就是我的服务总线和DocumentDB系统的设计方式。
从设计中删除服务总线以执行这些类型的操作,并使用DocumentDB作为服务总线。然后确保在对存储过程的单次调用中执行您希望被视为单个事务的所有操作,这将为其提供ACID全通或全失败事务保证。您可能仍然可以将服务总线用于其他事情,而不是这些。
由于这两个系统是独立的,我能想到的另一种方法就是采取补偿措施。例如,您可以尝试使用DocumentDB。如果涉及多个文档或读取后写入相同文档,请在存储过程中执行此操作,以便为其提供ACID事务保证。务必以可以逆转它的方式撰写交易(补偿它)。如果DocumentDB操作没有失败,那么尝试服务总线操作。如果失败,则在DocumentDB上执行补偿事务。
注意,第3个选项仍然不是一个完美的解决方案。如果在您尝试服务总线操作所花费的时间内,在DocumentDB端已经完成了某些操作,这使得无法以一致的方式反转该方面,您现在将处于不一致状态。如果系统以不可忽略的方式发生,请确保系统抛出红色标记。由您来建模系统并确定它的罕见程度。请记住,与非常罕见的事件一起生活是可以的。想想GUID是如何组成的。仍有可能会发生碰撞。这是非常罕见的,你不需要担心它。
即使它并非“非常”罕见,您仍可能希望这样做取决于罕见程度和有多大程度的不一致性。假设,服务总线动作失败的概率为1 / 10,000,补偿交易失败的概率为1 / 10,000。那么两者发生的几率都是1亿分之一。如果你每个月做1,000,000个这样的话,那么第一个出现的中位数需要50个月,并且它们将相隔大约100个月。然后确定有多糟糕。如果花费10,000美元来修复其中一个(向客户支付SLA违规+人工以手动修复),您是否可以每100个月支付一次费用?
我可能会进一步分析并创建一个Monty Carlo模拟,用于测试模型中的不确定性。你可能不知道它是否是万分之一的机会,你可能会说,我有70%肯定或90%确定它在1 / 1,000到1 / 100,000之间。蒙特卡罗模拟将允许您在该范围内“掷骰子”并产生第一年成本的概率曲线。输出会说出这样的结论:“第一年有10%的几率使我们至少花费10万美元;第一年我们至少花费10,000美元的成本是40%,而90%是90%第一年它至少花费我们1000美元的机会。
大多数工程师不习惯这样的概率决策,但这就是我的写作,演讲和咨询的内容,我已经习惯于帮助工程组织学会以这种方式做出决策,主要是他们的模型加载以及他们如何预测特定范围何时完成,但有时我会做上述模型。结果使团队对他们的决定更有信心。