当在队列之间发送消息时,TransactionScope是否会升级到MSDTC?

5
我有一个简单的流程,从一个队列读取消息,处理消息并输出到另一个队列。我尝试将这个转移包装在TransactionScope中,以使来自输入队列的读取和写入到输出队列发生在同一个事务中。
然而,似乎正在使用MSDTC来进行此事务,结果比使用标准的MessageQueueTransaction慢得多。这样应该发生吗?我认为只有当作用域涉及例如消息队列读取和数据库写入时,TransactionScope才会升级到外部事务,而不是仅涉及多个消息队列。
谢谢。
编辑:目前这一切都在我的笔记本电脑上进行,所以我确定没有其他机器参与。
我还想补充说,我正在通过检查Windows的“组件服务”捷径(即本地DTC / 事务列表)来确认是否发生了升级事务。我可以看到事务进入并离开此屏幕,我认为这意味着事务已经被升级。我在这方面的假设错了吗?
编辑2:当我只写入单个队列时,我也会得到相同的行为!即:
using (var ts = new TransactionScope())
{
    using (var q = new MessageQueue("..."))
    {
        /* write data */
    }

    ts.Complete();
}

尽管队列在本地机器上,我可以看到DTC与上述内容一起使用。


队列与应用程序的关系在哪里?同一台机器上?不同的机器上? - John Breakwell
你是否正在使用集群服务器? - Jens H
不,目前这些都是在我的笔记本电脑上进行的本地操作。我已经更新了我的问题并进行了一些澄清。 - Barguast
3个回答

3

看起来TransactionScope仅处理与消息队列有关的外部事务。如果您想让它成为仅内部事务,则必须使用MessageQueueTransaction。这在处理SQL事务时有所不同,只有在需要升级事务时才会升级事务,这是让我感到困惑的原因。


0

请看一下这篇MSDN文章:交易管理升级

这个列表列出了典型的升级行为,例如(高亮部分是我的):

当您希望将事务提供给另一个位于另一个应用程序域中(包括跨进程和机器边界)的对象,且这些对象在同一台计算机上时,System.Transactions 基础结构会自动将该事务升级为由 Microsoft 分布式事务协调器 (MSDTC) 管理。如果注册了另一个持久性资源管理器,也会发生升级。升级后,事务将保持其升级状态,直到完成。

正如您所看到的,即使在同一台计算机上进行操作,升级也可能会发生。(例如,我最近就曾遇到过一个问题,当我从同一(集群)服务器的 Windows 服务访问 MS SQL 数据库时。)

此外,在处理过程中涉及到 WCF 服务时,也可能会发生此情况。


在这种情况下,是从一个队列转移到另一个队列,两个队列都在同一台机器上。这些队列都是MessageQueue类型的,因此WCF并不涉及其中。我会仔细阅读文章,看看它是否能给我一些线索。谢谢。 - Barguast
关于Jens对“同一台机器”的评论,集群服务器的定义至少包括两台机器(一个或多个物理机器,一个或多个虚拟机器)。 - John Breakwell
目前我正在我的笔记本电脑上进行测试,所以我确定没有任何机器边界被跨越,无论是虚拟的还是实际的。 - Barguast

0
“看起来TransactionScope只处理与消息队列相关的外部事务。”这个说法是不正确的。TransactionScope可以处理消息队列中的本地事务,只是它使用MSDTC来实现。

1
我认为这里可能存在术语误解。Barguast 回复中的“external”可能是指您自己代码之外的交易,在消息队列的情况下,这有点令人困惑,因为该交易可能来自另一台机器(外部交易)。 - Donald Fraser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接