通过 MSMQ 的 WCF 的随机 MSDTC 异常
我们有一个使用 NetMsmqBinding 通过 MSMQ 执行 WCF 调用的服务。不幸的是,我们看到 MSDTC 服务中随机出现 AccessViolationException(在数千次调用后每隔几天出现一次)。此错误仅发生在物理较旧的 XP 生产系统上,我无法在开发中重新创建它。我什至在虚拟机中进行了映像和运行实际生产实例,但一切都稳定运行了好几天。我比较了我能找到的每个 MSMQ 和 MSDTC 相关 dll 的版本号,它们都匹配。最近已应用 Windows 更新。 WCF 端点以单个 InstanceContextMode 运行,并且 ConcurrencyMode 也设置为 single。
除了实际解决问题之外,我是否可以捕获/恢复以下错误?
有办法阻止 NetMsmqBinding 促进事务吗?除了队列本身之外,不使用任何其他资源。
The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
at System.Transactions.Oletx.IDtcProxyShimFactory.BeginTransaction(UInt32, System.Transactions.Oletx.OletxTransactionIsolationLevel, IntPtr, System.Guid ByRef, System.Transactions.Oletx.ITransactionShim ByRef)
at System.Transactions.Oletx.OletxTransactionManager.CreateTransaction(System.Transactions.TransactionOptions)
at System.Transactions.TransactionStatePromoted.EnterState(System.Transactions.InternalTransaction)
at System.Transactions.EnlistableStates.Promote(System.Transactions.InternalTransaction)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(System.Transactions.Transaction)
at System.Transactions.TransactionInterop.GetDtcTransaction(System.Transactions.Transaction)
at System.ServiceModel.Channels.MsmqQueue.GetNativeTransaction(System.ServiceModel.Channels.MsmqTransactionMode)
at System.ServiceModel.Channels.MsmqQueue.ReceiveCoreDtcTransacted(System.ServiceModel.Channels.MsmqQueueHandle, System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.ReceiveCore(System.ServiceModel.Channels.MsmqQueueHandle, System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.TryReceiveInternal(System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.TryReceive(System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode)
at System.ServiceModel.Channels.MsmqReceiveHelper.TryReceive(System.ServiceModel.Channels.MsmqInputMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, System.ServiceModel.Channels.MsmqMessageProperty ByRef)
at System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(System.TimeSpan, System.ServiceModel.Channels.Message ByRef)
at System.ServiceModel.Channels.SecurityChannelListener`1+SecurityInputChannel[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].TryReceive(System.TimeSpan, System.ServiceModel.Channels.Message ByRef)
at System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(System.TimeSpan, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(System.TimeSpan, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ChannelHandler.TryTransactionalReceive(System.Transactions.Transaction, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ChannelHandler.TransactedLoop()
at System.ServiceModel.Dispatcher.ChannelHandler.SyncTransactionalMessagePump()
at System.ServiceModel.Dispatcher.ChannelHandler.OnStartSyncMessagePump(System.Object)
at System.Runtime.IOThreadScheduler+ScheduledOverlapped.IOCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Runtime.Fx+IOCompletionThunk.UnhandledExceptionFrame(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
We have a service that is performing WCF calls over MSMQ using the NetMsmqBinding. Unfortunately we're seeing a random (every few days after thousands of calls) AccessViolationException coming out of the MSDTC service. This error is only happening on physically-older XP production systems and I can't re-create it in dev. I've even resorted to imaging and running actual production instances in VMs but everything runs solid for days. I've compared version numbers of every MSMQ and MSDTC-related dlls I can find and they all match. Windows Updates have been applied recently. The WCF endpoints are running with an single InstanceContextMode and the ConcurrencyMode is set to single as well.
Short of actually resolving the issue, is there anyway I can catch/recover from the following error?
Is there a way to keep the NetMsmqBinding from promoting the transaction? We're not using any other resources than the queues themselves.
The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
at System.Transactions.Oletx.IDtcProxyShimFactory.BeginTransaction(UInt32, System.Transactions.Oletx.OletxTransactionIsolationLevel, IntPtr, System.Guid ByRef, System.Transactions.Oletx.ITransactionShim ByRef)
at System.Transactions.Oletx.OletxTransactionManager.CreateTransaction(System.Transactions.TransactionOptions)
at System.Transactions.TransactionStatePromoted.EnterState(System.Transactions.InternalTransaction)
at System.Transactions.EnlistableStates.Promote(System.Transactions.InternalTransaction)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(System.Transactions.Transaction)
at System.Transactions.TransactionInterop.GetDtcTransaction(System.Transactions.Transaction)
at System.ServiceModel.Channels.MsmqQueue.GetNativeTransaction(System.ServiceModel.Channels.MsmqTransactionMode)
at System.ServiceModel.Channels.MsmqQueue.ReceiveCoreDtcTransacted(System.ServiceModel.Channels.MsmqQueueHandle, System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.ReceiveCore(System.ServiceModel.Channels.MsmqQueueHandle, System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.TryReceiveInternal(System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, Int32)
at System.ServiceModel.Channels.MsmqQueue.TryReceive(System.ServiceModel.Channels.NativeMsmqMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode)
at System.ServiceModel.Channels.MsmqReceiveHelper.TryReceive(System.ServiceModel.Channels.MsmqInputMessage, System.TimeSpan, System.ServiceModel.Channels.MsmqTransactionMode, System.ServiceModel.Channels.MsmqMessageProperty ByRef)
at System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(System.TimeSpan, System.ServiceModel.Channels.Message ByRef)
at System.ServiceModel.Channels.SecurityChannelListener`1+SecurityInputChannel[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].TryReceive(System.TimeSpan, System.ServiceModel.Channels.Message ByRef)
at System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(System.TimeSpan, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(System.TimeSpan, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ChannelHandler.TryTransactionalReceive(System.Transactions.Transaction, System.ServiceModel.Channels.RequestContext ByRef)
at System.ServiceModel.Dispatcher.ChannelHandler.TransactedLoop()
at System.ServiceModel.Dispatcher.ChannelHandler.SyncTransactionalMessagePump()
at System.ServiceModel.Dispatcher.ChannelHandler.OnStartSyncMessagePump(System.Object)
at System.Runtime.IOThreadScheduler+ScheduledOverlapped.IOCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Runtime.Fx+IOCompletionThunk.UnhandledExceptionFrame(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的服务配置为作为单例实例运行。当多个客户端在负载下调用服务时,您可能会遇到 DTC 线程问题。除非您绝对确定需要将服务作为单例运行并且服务代码是线程安全的,否则您应该使用每次调用或每次会话的 InstanceContextMode(取决于安全配置)。
您还可以尝试使用以下标记来标记服务操作方法实现:
并防止方法内的代码加入 MSMQ 创建的环境事务来处理您的消息。
Your service is configured to run as a singleton instance. You may be having threading issues with DTC when the service is called under load by multiple clients. Unless you're absolutely certain that you need to run the service as a singleton and the service code is thread safe, you should use a InstanceContextMode of per call or per session (depending on the security config).
You could also try to mark the service operation method implementation with:
and also prevent code inside the method from enlisting in the ambient transaction MSMQ creates to process your message.