3

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

这是一个例外:

System.ServiceModel.MsmqException (0xC00E0051):从队列接收消息时出错:无法识别的错误 -1072824239 (0xc00e0051)。确保 MSMQ 已安装并正在运行。确保队列可用于接收。在 System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(TimeSpan timeout, Message& message) 在 System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(TimeSpan timeout, RequestContext& requestContext) 在 System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(TimeSpan timeout, 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. 第二个事务在 60 秒后中止(抛出 MsmqException)
  6. wcf 主机 (IIS) 有时会出现故障(我有一些代码可以自动恢复它,显然这种行为在 .net 4 中已经改变)
    • 如果主机被破坏并自动恢复,下一条消息将再次发生
    • 如果主机没有损坏,则第二次事务将不会在下一次开始,一切都会正常工作:)。
    • 如果我回收 AppPool,问题又开始了
4

1 回答 1

0

我发现了问题。

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

我刚刚写了一个解决方案的帖子:http: //blog.jorgef.net/2011/07/msmqexception.html

我希望它有所帮助。

乔治

于 2011-07-20T04:51:16.363 回答