假设您有连接3个不同外部系统的应用程序。您需要更新所有内容3.如果发生故障,您需要回滚操作。 这不是一件难以实现的事情,但是说操作3失败了,当回滚时,操作1的回滚失败了!现在第一个外部系统处于无效状态......
我认为可能的解决方案是关闭应用程序并强制手动修复外部系统,但是又一次......它可能已经使用过这些信息(也许这就是它失败的原因),或者我们可能没有足够的访问权限。或者它甚至可能不是回滚动作的好方法!
是否有一些处理此类案件的好方法?
编辑:一些申请细节..
这是一个多用户Web应用程序。大部分工作都是通过预定的工作完成的(通过Quartz.Net),因此大多数操作都是在自己的线程中运行。某些用户操作应该触发更新多个系统的作业。外部系统有点不稳定。
我正在考虑更改应用程序以使用命令和工作单元模式
答案 0 :(得分:1)
两阶段提交(2PC)可能适用于此。
第一阶段是让各个数据库同意他们愿意继续提交。在您的示例中,数据库1将不会继续写入,直到确定所有三个数据库都已报告可以进行事务处理。
这与您描述的过程相比,这是一种“乐观”的方法 - 数据库1将假定事务应该通过,直到它以其他方式获知,并被迫回滚。
答案 1 :(得分:1)
您是否想进一步解释操作1的回滚如何失败?
它的目标是它之前的状态,所以它应该在逻辑上是一致的。可能存在网络故障等短暂问题,但可能的情况是,处理问题的最佳方法是重试,直到问题消失为止。
如果问题是后续事务在此期间锁定或更改了数据,那么您有一个更大的问题 - 您的事务不是原子的,并且回滚它们可能会导致其他事务的输出无效。 / p>
答案 2 :(得分:0)
根据应用程序的大小(单用户与企业),关闭应用程序可能是一个坏主意。
首先,我建议将3个外部应用中正在更改的信息的初始状态保存到您自己应用的本地存储中。这意味着,如果应用程序崩溃/回滚失败/等等,您至少可以确定回滚状态应该是什么。一旦事务成功提交,您就可以删除此数据。
当其中一个操作失败时该怎么办取决于3个外部系统的功能。我们假设其中一个系统包含员工数据。仅仅因为一个员工的地址由于交易失败而错误而关闭应用程序是过度的。无论何时访问员工的数据,只需检查失败的事务日志(即,保存3个外部应用程序的初始状态的本地存储)就更好了。如果该员工数据被标记为无效,则抛出一个错误,指示该记录处于无效状态且无法检索。
但是,如果整个外部系统因失败的交易而陷入混乱,那么是 - 你可以在这里做任何事情,但关闭你的应用程序,直到问题得到解决。
答案 3 :(得分:0)
Oddthinking的答案很好,但是因为实际上可靠做2PC非常困难。这在分布式计算社区已经有一段时间了,尽管很多人都会尽力忽略它。
如果您有兴趣深入研究这个领域,Paxos consensus algorithm是一个很好的起点。请注意,这是一个令人难以置信的难题,正是因为您提到的问题以及实际上无法构建真正可靠的消息传递系统以及在有限的时间内传递消息这一事实。 (要理解为什么会这样,请考虑someone with a backhoe可能会消除各个通信方之间的所有网络链接......)
我怀疑真正的解决方案是设计整个系统的架构以及如何在其中推出更改,以便在一个区域中丢失通信不是灾难性的。根据确切的细节,这可能也可能不容易做到。