让我们假设在有状态的服务中有一些这样的代码:
public async Task<bool> UpdateTheThing()
{
using (var tx = StateManager.CreateTransaction())
{
await UpdateLocalState(tx);
// point a
bool isOK = await otherServiceProxy.UpdateServiceState();
// point b
if(isOK)
{
await tx.CommitAsync();
}
return isOK;
}
}
如果在任何地方出现不好的事情,我们都很安全 - 交易将会处理 确保数据一致。如果在a点和b点之间发生了某些事情,我们可以 或者可能没有更新其他服务的状态。
如果发生的坏事是抛出异常,我们就可以做到 恢复其他服务上的状态,但如果我们的节点在那时关闭,我们就会 永远不会恢复状态。
我知道解决此类问题的一种方法是执行以下操作:
这是相当多的基础设施。我正在寻找更简单方法的建议。
我注意到Service Fabric样本似乎都没有处理这个问题。
答案 0 :(得分:1)
我认为您在上面描述的六步法是正确的。 Service Fabric目前不支持跨服务交易:
UserVoice request to consider that feature
我推测,要么永远不会支持,要么以某种有限的方式支持。分布式系统中的事务一致性是已知的难题。这就是为什么最终一致性是现代云架构中当前首选模式的原因:
eventual consistency description
关于这个问题的更多背景知识:
至于你的解决方案,我会说你的方法虽然不是很简单,但却是正确的方法。如上所述,UpdateTheThing()具有两个状态的隐含概念......“没有更新”和“一切都已更新”。您需要引入调用者明确知道的一些其他状态,并相应地处理:
您还可能希望在超过某个超时期限之后未收到远程更新确认时出现错误情况,等等。您也可能需要正式的状态进行重试行为等。
根据您的具体情况,除此之外显然还有很多复杂性。关键是你可能不希望UpdateTheThing()试图从调用者隐藏它的复杂性......调用者需要知道可能的状态并适当地处理/响应它们。
正如你所说的复杂,但这是分布式工作的本质(在云端或其他方面)。
祝你好运!