如何避免加入 NServiceBus 的环境 TransactionScope?
How can I avoid joining NServiceBus' ambient TransactionScope?
我们有一项服务可以与 SQL 服务器或 Oracle 后端一起使用。我们刚刚开始添加消息传递功能,以允许我们的服务与仅 Oracle 的应用程序进行通信,并决定使用 NServiceBus。决定放置 NServiceBus subscriptions/queue/etc。在应用程序的数据库上,因此 NServiceBus 始终使用 Oracle。
当服务与 SQL 服务器后端一起使用时,一切正常。但是当我们尝试将服务与 Oracle 后端(一个与应用程序和 NServiceBus 使用的数据库完全独立的数据库,通常在不同的服务器上)一起使用时,我们会遇到异常。
异常详情:
- 异常文本:"Connection is already part of a local or a distributed transaction" 或有时 "Unable to enlist in a distributed transaction"(最小 VM 测试环境反而得到 "Unable to load OraMTS")
- 我们数据库层调用
connection.Open()
时出现异常
- 连接的连接字符串是标准的
Data Source=foo;User Id=bar;Password=baz
- 该服务正在使用非托管 Oracle 提供程序
- 该服务在开始处理消息时使用装饰器进行连接,然后断开连接;删除装饰器并在服务启动时(在设置 NServiceBus 之前)连接服务可以解决问题,但这意味着如果该连接发生任何事情,则必须重新启动服务
异常文本让我们认为连接正在尝试加入 NServiceBus 的 TransactionScope。那是对的吗?如果是这样,是否有一些选项我们可以添加到连接字符串或在连接本身上配置以避免加入环境 TransactionScope?
请注意,我们在代码中使用了 BeginTransaction;我们知道它不能很好地与 TransactionScope 一起使用,但我们以前从未在我们的代码中使用过 TransactionScope,并且不想成为 in TransactionScope,无论如何我们得到的异常甚至在我们进行 BeginTransaction 调用之前就已经发生了。
将Enlist=false
放入连接字符串。
这个问题的解决方案有点难以找到,因为每个人似乎都假设您要么希望所有连接都使用分布式事务,要么 none 其中的连接使用分布式事务。但是我最终在 Microsoft Oracle 提供程序的 documentation 中发现您可以将 Enlist=false
添加到您的连接字符串以指示您不希望连接自动加入活动的分布式事务(显然仍然可能稍后手动加入分布式事务,但我没有仔细调查,因为它与我们的案例无关)。
我们有一项服务可以与 SQL 服务器或 Oracle 后端一起使用。我们刚刚开始添加消息传递功能,以允许我们的服务与仅 Oracle 的应用程序进行通信,并决定使用 NServiceBus。决定放置 NServiceBus subscriptions/queue/etc。在应用程序的数据库上,因此 NServiceBus 始终使用 Oracle。
当服务与 SQL 服务器后端一起使用时,一切正常。但是当我们尝试将服务与 Oracle 后端(一个与应用程序和 NServiceBus 使用的数据库完全独立的数据库,通常在不同的服务器上)一起使用时,我们会遇到异常。
异常详情:
- 异常文本:"Connection is already part of a local or a distributed transaction" 或有时 "Unable to enlist in a distributed transaction"(最小 VM 测试环境反而得到 "Unable to load OraMTS")
- 我们数据库层调用
connection.Open()
时出现异常
- 连接的连接字符串是标准的
Data Source=foo;User Id=bar;Password=baz
- 该服务正在使用非托管 Oracle 提供程序
- 该服务在开始处理消息时使用装饰器进行连接,然后断开连接;删除装饰器并在服务启动时(在设置 NServiceBus 之前)连接服务可以解决问题,但这意味着如果该连接发生任何事情,则必须重新启动服务
异常文本让我们认为连接正在尝试加入 NServiceBus 的 TransactionScope。那是对的吗?如果是这样,是否有一些选项我们可以添加到连接字符串或在连接本身上配置以避免加入环境 TransactionScope?
请注意,我们在代码中使用了 BeginTransaction;我们知道它不能很好地与 TransactionScope 一起使用,但我们以前从未在我们的代码中使用过 TransactionScope,并且不想成为 in TransactionScope,无论如何我们得到的异常甚至在我们进行 BeginTransaction 调用之前就已经发生了。
将Enlist=false
放入连接字符串。
这个问题的解决方案有点难以找到,因为每个人似乎都假设您要么希望所有连接都使用分布式事务,要么 none 其中的连接使用分布式事务。但是我最终在 Microsoft Oracle 提供程序的 documentation 中发现您可以将 Enlist=false
添加到您的连接字符串以指示您不希望连接自动加入活动的分布式事务(显然仍然可能稍后手动加入分布式事务,但我没有仔细调查,因为它与我们的案例无关)。