如何避免加入NServiceBus的环境TransactionScope?

3
我们的服务可以与 SQL Server 或 Oracle 后端配合使用。我们刚开始添加了消息传递功能,以便使我们的服务能够与仅支持Oracle的应用程序进行通信,决定采用 NServiceBus。决定将 NServiceBus 的订阅/队列等放置在应用程序的数据库上,这样 NServiceBus 就总是使用 Oracle。
当将服务用于 SQL Server 后端时,一切都很好。但是当我们尝试将服务与 Oracle 后端(通常位于不同服务器上,完全不同的数据库与应用程序及 NServiceBus 所使用的数据库)配合使用时,就会出现异常。
异常详细信息如下:
- 异常文本:“Connection is already part of a local or a distributed transaction”,有时会是“Unable to enlist in a distributed transaction”(最小VM测试环境中则为“无法加载OraMTS”) - 当我们的数据库层调用 `connection.Open()` 时,就会出现该异常。 - 连接的连接字符串为标准格式的 `Data Source=foo;User Id=bar;Password=baz` - 该服务使用非托管的 Oracle 提供程序 - 该服务使用一个装饰器,在处理消息时开始连接,然后在完成后断开连接;如果删除该装饰器并改为在启动时连接(在设置NServiceBus之前),可以解决问题,但这意味着如果该连接发生任何问题,则必须重新启动该服务。
异常文本使我们认为连接正在试图加入 NServiceBus 的 TransactionScope。如果是这样,那么有没有一些选项可以添加到连接字符串或在连接本身上进行配置,以避免加入环境事务范围?请注意,代码中使用了 `BeginTransaction`;我们知道它与 TransactionScope 不兼容,但我们之前从未在代码中使用过 TransactionScope,也不想位于 TransactionScope 中,在任何情况下,我们得到的异常是在我们甚至没有到达 `BeginTransaction` 调用之前就发生了。

这可能是由于分布式事务协调器(MSDTC)未运行或运行 NServiceBus 端点的用户帐户没有被允许使用 MSDTC。在您回答自己的问题时,您找到了一种方法来禁用它,但请确保您已经了解了影响。几乎没有任何保证您的消息将安全到达或发送。您可能会开始丢失消息。 - Dennis van der Stelt
@DennisvanderStelt NServiceBus将MSDTC列为要求,因此我们进行了双重检查。请注意,我们修改了我们连接到数据库的连接字符串,而不是NServiceBus的连接。 - Oblivious Sage
你双重检查了什么?MSMQ、SQL Server和Oracle都可以在同一个分布式事务中注册,但不一定需要这样做。你可以使用“TransactionScope”创建一个新的环境事务,并且不必进行注册。但这取决于你正在做什么,而我并不完全理解你在最后一条评论中试图实现什么。 - Dennis van der Stelt
@DennisvanderStelt 我们根本没有尝试使用分布式事务。我们的服务从NServiceBus接收消息,处理它们,并将结果存储在数据库中。但是当它尝试连接到数据库时,它一直被吸入NSB的分布式事务中。我们希望避免加入NSB的分布式事务,而不会搞乱NSB正在进行的任何操作,这就是下面的答案所实现的。 - Oblivious Sage
NServiceBus默认情况下不会创建分布式事务,而是因为使用了多个资源管理器才会创建。例如:MSMQ和SQL Server、SQL Server和Oracle、MSMQ和Oracle等。当从MSMQ读取数据并打开数据库连接时,这两个事务都将“吸入”分布式事务中。只使用一个资源管理器(例如仅使用Oracle)可以确保不会出现此情况。DTC提供高可靠性,但代价也相应较高。在放弃可靠性之前,我们可能需要三思而行。 - Dennis van der Stelt
1个回答

2
在连接字符串中加入Enlist=false
这个解决方案有些难以找到,因为每个人似乎都认为你要么希望所有连接使用分布式事务,要么不希望任何连接使用分布式事务。然而,最终我在Microsoft Oracle提供程序的文档中发现可以在连接字符串中添加Enlist=false来指示您不希望该连接自动加入活动分布式事务(显然仍然可以后期手动加入分布式事务,但由于与我们无关,我没有过多深入研究)。

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