我有一台承载许多后端NServiceBus端点的Windows 2008 R2服务器。依赖于NServiceBus.Host.exe主机(作为Windows服务安装)的所有服务都能够完美地与MSDTC交互,平均在一天内完成少量并发分布式事务。但是,有两个小的Web.API应用程序自我托管NServiceBus端点(作为发布者),在尝试处理订阅请求时不断收到以下错误:
NServiceBus.Transports.Msmq.MsmqDequeueStrategy接收错误 消息。 System.Transactions.TransactionAbortedException:The 交易已中止。 ---> System.Transactions.TransactionManagerCommunicationException: 与底层事务管理器的通信失败。 ---> System.Runtime.InteropServices.COMException:事务管理器 不可用。 (来自HRESULT的异常:0x8004D01B)at System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(字符串 nodeName,Guid resourceManagerIdentifier,IntPtr managedIdentifier, 布尔和放大器; nodeNameMatches,UInt32& whereaboutsSize,CoTaskMemHandle& whereaboutsBuffer,IResourceManagerShim& resourceManagerShim)at System.Transactions.Oletx.DtcTransactionManager.Initialize()--- 内部异常堆栈跟踪结束--- at System.Transactions.Oletx.OletxTransactionManager.ProxyException(收到COMException comException)at System.Transactions.Oletx.DtcTransactionManager.Initialize()at System.Transactions.Oletx.DtcTransactionManager.get_ProxyShimFactory() 在 System.Transactions.Oletx.OletxTransactionManager.CreateTransaction(TransactionOptions 物业) System.Transactions.TransactionStatePromoted.EnterState(InternalTransaction tx)---内部异常堆栈跟踪结束--- at System.Transactions.TransactionStateAborted.CheckForFinishedTransaction(InternalTransaction tx)在System.Transactions.Transaction.Promote()at System.Transactions.TransactionInterop.ConvertToOletxTransaction(交易 交易) System.Transactions.TransactionInterop.GetDtcTransaction(交易 交易) System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32超时, Int32操作,MQPROPS属性,NativeOverlapped *重叠, ReceiveCallback receiveCallback,CursorHandle cursorHandle,IntPtr 交易) System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan超时,Int32 action,CursorHandle游标,MessagePropertyFilter过滤器, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)at System.Messaging.MessageQueue.Receive(TimeSpan超时, MessageQueueTransactionType transactionType)at NServiceBus.Transports.Msmq.MsmqDequeueStrategy.ReceiveMessage(Func`1 接收) C:\ BuildAgent \工作\ 31f8c64a6e8a2d7c的\ src \ NServiceBus.Core \交通服务\ MSMQ \ MsmqDequeueStrategy.cs:行 313
其他一些说明:
来自以下对话的其他说明
答案 0 :(得分:2)
不是答案,但评论的时间太长了。
您的操作的哪个部分需要DTC?分布式事务在需要时自动登记,通常是在与两个不同的DTC支持的基础结构位(例如MSMQ和数据库)进行通信时。
你说你通过DTC追踪测试过 - 你的意思是DTC Ping吗?您是否通过在两台机器上运行(或者如果交易中涉及两个以上的机器的所有机器)进行测试? DTC工具非常深奥,其输出可能令人困惑。
此外,如果它在重新启动之前确实有效,是否可以重新启动重置防火墙设置?防火墙是导致DTC问题的常见原因。
另外,我假设您检查并重新检查了本地计算机上的DTC设置?您确定您的MSMQ队列设置为交易吗?
来自您的评论:
请注意,尝试出列时会发生此特定故障 来自本地私有MSMQ队列的消息[...]
堆栈跟踪使它看起来就是它所做的一切,但我怀疑它正在尝试出列,它也试图在多个服务器之间登记该事务。见下文。
为何选择MSDTC?这是支持一次性消息传递的原始方式 NServiceBus(见这里)。
是的,但我要问的是为什么特定的操作需要分布式事务。如果所有处理程序正在执行的是从队列中读取并(例如)将输出写入控制台,则MSDTC将永远不会被登记,即使处理程序包装在事务作用域中也是如此。它将简单地使用本地事务从队列中读取。升级到分布式事务是自动的,只有在需要支持多个基础架构时才会发生。
因此,如果您最近在将数据写入新数据库服务器的处理程序中部署了代码,那么您可能会遇到失败,因为您现在正在申请包含新服务器的事务,这可能是发生故障的地方。 / p>
因此,确定分布式事务中涉及的所有服务器是第一步。下一步是检查所有涉及的服务器上的DTC设置。如果DTC设置不是问题,我建议使用DTCPing测试服务器之间的通信。 NServiceBus documentation有一些使用DTCP的良好说明。
答案 1 :(得分:1)
什么"固定"对于我们而言,在生产环境中,我们将应用程序池标识用户添加到服务器上的本地Administrators组。遗憾的是,我们没有时间确定安全设置所需的设置,因为这不是其他类似服务器中的必需配置。此外,从安全角度来看,这不是最理想的解决方案,但在我们的特定情况下,我们愿意接受它。