【问题标题】:TransactionScope elevating to MSDTC when sending between queues?在队列之间发送时,TransactionScope 提升到 MSDTC?
【发布时间】:2012-09-14 15:48:23
【问题描述】:

我有一个简单的过程,它从一个队列中读取、处理消息并输出到另一个队列。我试图将此传输包装在 TransactionScope 中,以便从输入队列读取和写入输出队列都发生在同一个事务中。

但是,似乎正在使用 MSDTC 来执行此事务,因此它比使用标准 MessageQueueTransaction 慢得多。这应该发生吗?我的印象是 TransactionScope 只有在涉及范围时才会提升为外部事务,例如,读取消息队列和写入数据库,但如果只涉及多个消息队列则不会。

谢谢。

编辑:目前这一切都在我的笔记本电脑上,所以我确信不涉及其他机器。

我还想补充一点,我通过签入 Windows 的“组件服务”管理单元(即本地 DTC/事务列表)来确认正在发生升级的事务。我可以看到进入和离开这个屏幕的交易,我认为这意味着交易已经升级。我的假设错了吗?

编辑 2:当我只写一个队列时,我得到了相同的行为!即

using (var ts = new TransactionScope())
{
    using (var q = new MessageQueue("..."))
    {
        /* write data */
    }

    ts.Complete();
}

尽管队列在本地计算机上,但我可以看到 DTC 与上述一起使用。

【问题讨论】:

  • 与应用相关的队列在哪里?同一台机器?不同的机器?
  • 您使用的是集群服务器吗?
  • 不,目前这在我的笔记本电脑上都是本地的。我已经更新了我的问题并进行了一些澄清。

标签: .net sql-server transactions msmq transactionscope


【解决方案1】:

似乎 TransactionScope 只处理与消息队列有关的外部事务。如果您希望它仅是内部的,则必须使用 MessageQueueTransaction。这与仅在需要时才升级事务的 SQL 事务的工作方式不同,这让我感到困惑。

【讨论】:

    【解决方案2】:

    看看这篇 MSDN 文章:Transaction Management Escalation

    此列表典型的升级行为,例如(重点是我的):

    当您想将交易提供给另一个对象时在另一个 应用程序域(包括进程和机器边界) 在同一台计算机上,System.Transactions 基础架构 自动升级由 Microsoft 管理的事务 分布式事务协调器 (MSDTC)。升级也 如果您征用另一个持久资源管理器,就会发生这种情况。升级时, 交易保持在其提升状态下进行管理,直到其 完成。

    如您所见,提升不仅可以在您通过网络执行操作时发生,即使您在同一台计算机上执行操作也是如此。 (例如,我最近在同一(集群)服务器上从 Windows 服务访问 MS SQL 数据库时遇到了麻烦。)

    如果 WCF 服务在流程中的某处涉及,也会发生这种情况。

    【讨论】:

    • 在这种情况下,它是从一个队列到另一个队列的转移,两者都在同一台机器上。这些也是 MessageQueue 类型的队列,因此 WCF 不会加入其中。我会更详细地阅读这篇文章,看看它是否能给我一些线索。谢谢。
    • RE:Jens 关于“同一台机器”的评论。根据定义,集群服务器至少有两台机器(一台或多台物理机,一台或多台虚拟机)。
    • 目前我正在我的笔记本电脑上进行测试,所以我确信无论是否虚拟机都没有跨越机器边界。
    【解决方案3】:

    似乎 TransactionScope 只处理与消息队列有关的外部事务。

    这种说法是不正确的。 TransactionScope 将处理消息队列中的本地事务,只是它使用 MSDTC 来处理。

    【讨论】:

    • 我认为这里可能存在术语误解。巴古斯特回复中的外部可能是指您自己代码之外的事务,当消息队列的事务可能来自不同的机器(外部事务)时,这有点令人困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多