2

我们有一个使用 NetMsmqBinding 通过 MSMQ 执行 WCF 调用的服务。不幸的是,我们看到从 MSDTC 服务中随机出现的(在数千次调用后每隔几天)AccessViolationException。此错误仅发生在物理上较旧的 XP 生产系统上,我无法在 dev 中重新创建它。我什至求助于在虚拟机中成像和运行实际的生产实例,但一切都运行了好几天。我比较了我能找到的每个 MSMQ 和 MSDTC 相关 dll 的版本号,它们都匹配。最近已应用 Windows 更新。WCF 终结点使用单个 InstanceContextMode 运行,并且 ConcurrencyMode 也设置为单个。

没有真正解决问题,无论如何我可以从以下错误中捕获/恢复吗?

有没有办法阻止 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*)
4

1 回答 1

2

您的服务配置为作为单例实例运行。当多个客户端在负载下调用服务时,您可能会遇到 DTC 线程问题。除非您绝对确定需要将服务作为单例运行并且服务代码是线程安全的,否则您应该使用每次调用或每次会话的 InstanceContextMode(取决于安全配置)。

您还可以尝试使用以下方式标记服务操作方法实现:

[OperationBehavior(TransactionScopeRequired = false)]

并且还防止方法内的代码加入 MSMQ 创建的环境事务以处理您的消息。

于 2011-07-22T17:00:34.530 回答