【问题标题】:Random MSDTC exception with WCF over MSMQWCF over MSMQ 的随机 MSDTC 异常
【发布时间】:2011-07-22 14:35:49
【问题描述】:

我们有一个使用 NetMsmqBinding 在 MSMQ 上执行 WCF 调用的服务。不幸的是,我们看到一个随机的(在数千次调用后每隔几天)AccessViolationException 来自 MSDTC 服务。此错误仅发生在物理上较旧的 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*)

【问题讨论】:

  • 你知道哪一行出错了你能把那部分代码贴出来吗?
  • 我无法重新创建它,更不用说附加调试器了。堆栈跟踪来自事件查看器,不显示我的任何代码。我不知道这是否意味着我的代码参与了。

标签: .net wcf msmq msdtc netmsmqbinding


【解决方案1】:

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

您也可以尝试将服务操作方法实现标记为:

[OperationBehavior(TransactionScopeRequired = false)]

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2014-07-18
    • 2020-05-02
    • 2012-11-28
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多