Transactions 分布式事务如何工作(如MSDTC)?

Transactions 分布式事务如何工作(如MSDTC)?,transactions,acid,mstdc,Transactions,Acid,Mstdc,我模糊地理解了常规ACID事务是如何工作的。在数据库上执行某些工作的方式是,在设置某种提交标志之前,工作不会得到确认。提交部分基于一些基本假设(比如单个磁盘块写入是原子的)。如果发生灾难性错误,您可以在恢复阶段清除未提交的数据 分布式事务是如何工作的?在一些MS文档中,我读到您可以通过某种方式跨数据库和文件系统(以及其他内容)执行事务 这项技术可以(也可能是)用于安装程序,您希望程序完全安装或完全不安装。您只需在安装程序开始时开始一个事务。接下来,您可以连接到注册表和文件系统,进行定义安装的更改

我模糊地理解了常规ACID事务是如何工作的。在数据库上执行某些工作的方式是,在设置某种提交标志之前,工作不会得到确认。提交部分基于一些基本假设(比如单个磁盘块写入是原子的)。如果发生灾难性错误,您可以在恢复阶段清除未提交的数据

分布式事务是如何工作的?在一些MS文档中,我读到您可以通过某种方式跨数据库和文件系统(以及其他内容)执行事务

这项技术可以(也可能是)用于安装程序,您希望程序完全安装或完全不安装。您只需在安装程序开始时开始一个事务。接下来,您可以连接到注册表和文件系统,进行定义安装的更改。作业完成后,只需提交,或者在安装因某种原因失败时回滚。这个神奇的分布式事务协调器会自动为您清理注册表和文件系统

两个完全不同的系统怎么可能以这种方式进行交易?在我看来,总是有可能让系统处于不一致的状态,文件系统已经提交了更改,而注册表没有。我认为在MSDTC中,甚至可以通过网络执行事务

我已经读过了,但感觉这只是解释的开始,第4步应该大大扩展

编辑:根据我收集的信息,可以通过两阶段提交()来完成。读了这篇文章后,我仍然没有100%理解这个方法,似乎在步骤之间有很大的误差空间。

关于“步骤4”:

事务管理器负责协调 与资源经理一起确保 所有人都成功地完成了要求的任务 因此,如果完成了工作,则不进行任何工作 保持酸性

当然,这需要所有参与者提供适当的接口和(无错误)实现。界面大致如下所示:

public interface ITransactionParticipant {
    bool WouldCommitWork();
    void Commit();
    void Rollback();
}
提交时事务管理器询问所有参与者是否愿意提交事务。只有当参与者能够在所有允许的错误条件(验证、系统错误等)下提交此事务时,他们才可以断言这一点。在所有参与者都声明了提交事务的能力之后,管理者向所有参与者发送
commit()
消息。如果任何参与者引发错误或超时,则整个事务将中止并回滚单个成员


该协议要求参与者在声明其提交能力之前记录其整个事务内容。当然,这必须在一个特殊的本地事务日志结构中才能从各种故障中恢复。

如果参与者a和B,a提交并返回成功,然后B提交并返回失败,那么会发生什么情况?但在a回滚之前,网络会断开?另一种情况是网络故障可能会阻止B提交。在WouldCommitWork()上返回true之后,B可能不会在Commit()上失败,并且在所有参与者在WouldCommitWork()上返回true之前,A不会提交。协议的所有步骤都有相关的超时,当命中时会导致自动回滚。如果集群的某个部分出现故障,则必须重播未出现故障的成员的日志才能再次加入。针对拜占庭式错误的防故障集群是一个热门的研究课题,需要两个以上的参与者。B防止失败的唯一方法是锁定可能导致失败的任何更改,但好吧,所以请抓起第一个选项。OTOH硬件故障仍然存在。-我感兴趣的情况是,当两个系统继续向其他客户端提供服务时,任何链接都可能失败。在这种情况下,即使链路断开,系统也需要保持一致。我不知道他们如何才能就是否提交事务达成一致,并确保每个人都得出相同的结论。事实上,我认为维基百科的两阶段提交页面上列出的假设解决了我的问题:“没有节点永远崩溃,预写日志中的数据在崩溃中永远不会丢失或损坏”。我认为这意味着,当节点最终备份(网络或硬件)时,它最终将被提交。确切地说:一旦单个节点实际提交了
committed()
,事务已提交,在此之后的任何故障恢复都必须注意保持事务已提交。存在很大的错误空间。特别是,它依赖于“提交准备”始终有效。现实不同。