MSDTC 推广原因
Posted
技术标签:
【中文标题】MSDTC 推广原因【英文标题】:Reason for MSDTC promotion 【发布时间】:2015-07-09 20:31:51 【问题描述】:Reason for System.Transactions.TransactionInDoubtException 提到将事务提升为 MSDTC 的三个原因。前两个是众所周知的,但是第三个原因如下:
3.如果您的代码中运行了“try/catchretry if timeout/deadlock”逻辑,那么当事务位于 System.Transactions.TransactionScope 内时,这可能会导致问题,因为发生超时或死锁时,SQL Server 会自动回滚事务。
当我的一个服务器应用程序处于严重负载 (SQL 2012) 时,我在其中一个服务器应用程序中看到了这种行为。我已经广泛尝试谷歌搜索,但我没有找到更多信息。有没有人可以参考有关此主题的其他信息?
谢谢,
拉里
【问题讨论】:
您有什么症状?只有那个例外?为什么这个例外是个问题?您的重试逻辑应该会吞下它。 我们有嵌套事务。内部有重试循环。在重负载下,重试循环超时,回滚,升级到 MSDTC,重试。大多数时候它会成功,但有时我也会遇到 MSDTC 失败。 MSDTC 故障会导致其中一个事务回滚,而另一个则不会。 您知道 SQL Server 和 System.Transactions 都不支持嵌套事务吗? 我们有嵌套事务,内部有重试循环。在负载下,重试循环超时、回滚并升级。有时我们也会遇到 MSDTC 故障。 MSDTC 失败会导致一个事务回滚,而另一个则不会。我很好奇为什么我们会升级到 MSDTC。最初引用的帖子说我们正在经历的事情可能会发生,但没有详细说明细节。我们假设有时连接变得如此 FUBAR,以至于底层代码放弃/关闭它并打开一个新连接,从而导致嵌套连接,并升级到 MSDTC。拉里 那么您正在通过 MSDTC 连接的两个连接上运行两个事务?您不能在一个连接上运行两个事务。它实际上只是一个引用计数为 2 的 tran。 【参考方案1】:我猜我们实际上是在一个引用计数为 2 的连接上运行一个事务。我同意这是假的,应该重新编码。
这本身不是问题。
但是,有时内部事务会回滚并重试
问题是回滚会回滚所有内容。你不能孤立地重试“内部”工作。 (是的,这将非常有用,但 SQL Server 不支持它。)
这看起来会为内部事务启动第二个连接。这将导致调用 MSDTC 以尝试协调。
这是没有实际意义的,因为此时“外部”作品已被破坏。
这个问题没有很好的解决方案。最好的策略可能是只有一个事务并重试外部和内部工作作为一个单元。重试总是必须重试整个事务。您可以根据需要使用事务“引用计数”,但不能使用它来回滚。
SQL Server 的一个特别令人讨厌的特性是无法预测任何特定错误是否会导致事务回滚。因此,它是从不处理 SQL Server 错误并始终声明事务丢失的最干净的方法。 (SQL Server 必须这样做没有技术原因。这只是一个愚蠢的设计选择。)
【讨论】:
以上是关于MSDTC 推广原因的主要内容,如果未能解决你的问题,请参考以下文章