繁体   English   中英

处理nservicebus消息时如何使用ADO打开多个SQL连接

[英]How to open multiple sql connections with ADO when handling an nservicebus message

我有一个使用NServiceBus的消息处理程序,该消息处理程序需要在两个不同的数据库上执行SQL代码。 连接字符串具有不同的初始目录,但其他方面相同。

收到消息后,第一个sql连接成功打开,但是第二个sql连接导致调用.Open时引发以下异常。

分布式事务管理器(MSDTC)的网络访问已被禁用。 请使用组件服务管理工具在MSDTC的安全配置中为网络访问启用DTC。

我们不使用MSDTC。

这是失败的代码。 它将在connB.Open()上失败

public void Handle(MyMsgCmd message)
        {
            using (SqlConnection connA = new SqlConnection(myConnectionStringA))
            {
                connA.Open();
            }

            using (SqlConnection connB = new SqlConnection(myConnectionStringB))
            {
                connB.Open();
            }
        }

从命令行应用程序或Web应用程序运行时,相同的代码也可以正常工作。 仅当从NServiceBus调用该异常时,才会引发该异常。

这些连接中的每一个都将在第一次打开或单独打开时成功打开,但是只要存在第二个连接,即使已知第二个连接都将始终无法打开,但会出现相同的异常。

是否需要其他配置才能与NServiceBus依次打开多个连接?

默认情况下,NServiceBus看起来将每个消息处理程序包装在事务中,并且除非启用了MSDTC,否则导致对同一消息处理程序内不同数据库连接的查询失败。

我可以使用BusConfiguration.Transactions()。DoNotWrapHandlersExecutionInATransactionScope()禁用它

您可以在NServiceBus文档中找到有关交易的更多信息。

这不仅与NServiceBus无关,我们只是提供了不同的连接传输方式(例如MSMQ,Azure服务总线等),持久性和您自己的数据库。

但是,即使没有NServiceBus,在连接到两个数据库时,您也需要分布式事务,或者确保该事务不会升级为分布式事务。 问题是,如果没有分布式事务,则当一个事务成功提交时,另一事务可能会失败。 结果您的两个数据库不再同步或不一致。

如果存储了DatabaseA中的订单,并在DatabaseB中跟踪了库存,则可以从库存中扣除1,但是由于交易失败,该订单可能永远不会存储。 您需要自己补偿而无需分布式事务。

并不是说分布式事务始终是必经之路。 您可能没有使用它们,因为您的DBA不喜欢它们。 MSDTC始终在您的数据上放置可序列化的事务,这些事务具有最重的锁。 打开它们的时间越长,需要等待的并发运行的事务越多。 软件中可能存在巨大的性能问题。

另一方面,创建补偿交易可能非常非常困难。 考虑一下数据库A可能失败,数据库B可能成功的事实。 但是消息发生了什么? 它从队列中消失了吗? 还是将其保留在队列中并再次处理? 数据库B是否会因重复数据而再次成功

幸运的是,您已经在使用NServiceBus。 您可能想查看可以帮助解决其中一些问题的发件箱功能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM