60秒后MsmqException(0xC00E0051)

时间:2011-07-14 06:49:29

标签: wcf msmq netmsmqbinding

我正在将netMsmqBinding与事务队列一起使用,虽然调用WCF服务没有问题,但服务在处理消息后仅60秒就抛出了MsmqException。

这是一个例外:

  

System.ServiceModel.MsmqException(0xC00E0051):从队列接收消息时发生错误:无法识别的错误   -1072824239(0xc00e0051)。确保已安装并运行MSMQ。确保队列可用于接收。在   System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(时间跨度   超时,消息&消息)   System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(时间跨度   超时,RequestContext& requestContext)at   System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(时间跨度   超时,RequestContext&的RequestContext)

我做了一些研究,调试和跟踪,我发现当收到新消息时,会打开两个事务,第一个事务在服务执行后提交,但第二个事务从未提交,所以60秒后,DTC中止它抛出MsmqException。 这是操作定义:

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SomeOperation(SomeParameter parameter)
{
  // business logic
}

有关正在发生的事情的任何想法,以及如何解决此问题?

更新

配置:

<netMsmqBinding>
  <binding name="TransactionalMsmqBinding" exactlyOnce="true" deadLetterQueue="System" receiveErrorHandling="Move">
    <security mode="None"/>
  </binding>
</netMsmqBinding>
...
<service name="SomeNamespace.SomeService">
  <endpoint contract="SomeNamespace.ISomeService" bindingConfiguration="TransactionalMsmqBinding" binding="netMsmqBinding" address="net.msmq://localhost/private/services/someservice.svc">
  </endpoint>
  <endpoint contract="SomeNamespace.IAnotherService" bindingConfiguration="TransactionalMsmqBinding" binding="netMsmqBinding" address="net.msmq://localhost/private/services/anotherservice.svc">
  </endpoint>
</service>

服务实施:

[ExceptionShieldingBehavior(typeof(ArgumentValidationException), typeof(ValidationServiceException))]
[AuthorizationAndAuditBehaviour]
[ServiceBehavior(Namespace = GlobalConstants.ServiceContractNamespace)]
public class SomeService: ISomeService, IAnotherService
{
  [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
  public void SomeOperation(SomeParameter parameter)
  {
    // business logic
  }

  [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
  public void AnotherOperation(AnotherParameter parameter)
  {
    // business logic
  }
}

服务合同:

[ServiceContract(Namespace = GlobalConstants.ServiceContractNamespace)]
public interface ISomeService
{
  [OperationContract(IsOneWay = true)]
  void SomeOperation(SomeParameter parameter);
}

[ServiceContract(Namespace = GlobalConstants.ServiceContractNamespace)]
public interface IAnotherService
{
  [OperationContract(IsOneWay = true)]
  void AnotherOperation(AnotherParameter parameter);
}

完成行为

  1. 客户端发送消息
  2. 服务已激活
  3. DTC启动两个事务(我可以在DTC监视器和TransactionManager.DistributedTransactionStarted事件中看到它们)
  4. 操作完成后第一个事务完成
  5. 第二个事务在(抛出MsmqException)60秒后中止
  6. wcf主机(IIS)有时会出现故障(我有一些代码automatically recover it,显然这种行为在.net 4中有所改变)
    • 如果主机已损坏并自动恢复,则会在下一条消息
    • 上再次发生
    • 如果主机没有损坏,第二次交易将不会在下次启动,一切都会顺利运行:)。
    • 如果我回收AppPool,问题又重新开始

1 个答案:

答案 0 :(得分:0)

我找到了问题。

由于我使用两个不同的msmq端点公开相同的服务,出于某种奇怪的原因,SMSvcHost.exe进程激活相同的端点两次。

我刚刚用解决方案撰写了一篇文章:http://blog.jorgef.net/2011/07/msmqexception.html

我希望它有所帮助。

豪尔赫