![](/img/trans.png)
[英]How to implement message queuing and handling in AWS with NServiceBus
[英]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.