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

Posted

技术标签:

【中文标题】分布式事务如何工作(例如 MSDTC)?【英文标题】:How do distributed transactions work (eg. MSDTC)? 【发布时间】:2010-09-08 12:36:26 【问题描述】:

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

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

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

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

我看过http://blogs.msdn.com/florinlazar/archive/2004/03/04/84199.aspx,但感觉只是解释的开始,第四步应该有很大的扩展。

编辑:根据我在http://en.wikipedia.org/wiki/Distributed_transaction 上收集到的信息,它可以通过两阶段提交 (http://en.wikipedia.org/wiki/Two-phase_commit) 来完成。看完这篇,我还是没有100%理解这个方法,看来步骤之间有很大的误差空间。

【问题讨论】:

这里很大的错误空间。特别是,它依赖于“COMMIT PREPARED”始终有效。现实不同。 【参考方案1】:

关于“第4步”:

事务管理器协调 与资源经理一起确保 都成功完成了请求 如果完成,工作或不工作,因此 维护 ACID 属性。

这当然要求所有参与者提供正确的接口和(无错误的)实现。界面大概是这样的:

public interface ITransactionParticipant 
    bool WouldCommitWork();
    void Commit();
    void Rollback();

事务管理器在提交时询问所有参与者是否愿意提交事务。只有当参与者能够在所有允许的错误条件(验证、系统错误等)下提交此事务时,参与者才能断言这一点。在所有参与者都断言了提交事务的能力之后,管理器将Commit() 消息发送给所有参与者。如果任何参与者引发错误或超时,则整个事务中止并且个别成员被回滚。

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

【讨论】:

如果你有参与者 A 和 B,A 被提交并返回成功,然后 B 被提交并返回失败,但在 A 回滚之前,网络会掉线,会发生什么?另一种情况是网络故障可能会阻止 B 被提交。 B 在 WillCommitWork() 上返回 true 后可能不会在 Commit() 上失败,并且在所有参与者在 WillCommitWork() 上返回 true 之前不会提交 A。协议的所有步骤都有相关的超时,当命中时会导致自动回滚。如果集群的一部分发生故障,它将必须重播来自非故障成员的日志才能再次加入。针对拜占庭错误的故障证明集群是一个热门研究课题,需要两个以上的参与者。 B 可以防止失败的唯一方法是锁定任何可能导致失败的更改,但是可以,所以从第一个选项开始。 OTOH 硬件故障仍然存在。 -- 我感兴趣的情况是,在两个系统继续向其他客户端提供服务的情况下,任何链接都可能出现故障。在这种情况下,即使在掉线链路断开时,系统也需要保持一致。我看不出他们如何就是否要提交事务达成一致,并确保每个人都得出相同的结论。 实际上,我认为我的担忧可以通过***的两阶段提交页面上列出的假设得到解决:“没有节点永远崩溃,预写日志中的数据永远不会在崩溃中丢失或损坏”。我认为这意味着当节点最终备份(网络或硬件)时,它最终会被提交。 完全正确:一旦单个节点实际拥有Committed(),事务 提交,并且在此之后的任何故障恢复都必须注意保持事务已提交。

以上是关于分布式事务如何工作(例如 MSDTC)?的主要内容,如果未能解决你的问题,请参考以下文章

已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。

已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。

SqlServer & Windows 可更新订阅立即更新启用分布式事务协调器(MSDTC)

Azure 无法将事务编组为弹性事务的传播令牌(适用于 MSDTC)

MSDTC故障排除

为啥我的 MSDTC 事务没有在我的 localhost 环境中正确回滚?