3

トランザクション キューで netMsmqBinding を使用しています。WCF サービスは問題なく呼び出されますが、サービスはメッセージが処理されてからわずか 60 秒後に MsmqException をスローします。

これは例外です:

System.ServiceModel.MsmqException (0xC00E0051): キューからメッセージを受信中にエラーが発生しました: 認識できないエラー -1072824239 (0xc00e0051)。MSMQ がインストールされ、実行されていることを確認します。キューが受信できることを確認してください。System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive (TimeSpan タイムアウト、Message& メッセージ) で System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive (TimeSpan タイムアウト、RequestContext& requestContext) で System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive (TimeSpan タイムアウト、RequestContext& requestContext) )

いくつかの調査、デバッグ、トレースを行ったところ、新しいメッセージを受信すると 2 つのトランザクションが開かれ、最初のトランザクションはサービスの実行直後にコミットされますが、2 つ目のトランザクションは決してコミットされないため、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 は 2 つのトランザクションを開始します (DTC モニターと TransactionManager.DistributedTransactionStarted イベントで確認できます)。
  4. 操作が終了するとすぐに最初のトランザクションが終了します
  5. 2 番目のトランザクションは 60 秒後に中止されます (MsmqException がスローされます)。
  6. wcf ホスト (IIS) に障害が発生することがあります (自動的に回復するコードがいくつかあります。.net 4 でこの動作が変更されたようです)。
    • ホストが壊れて自動的に回復した場合、次のメッセージですべてが再び発生します
    • ホストが壊れていなければ、次回は 2 番目のトランザクションは開始されず、すべて問題なく動作します :)。
    • AppPool をリサイクルすると、問題が再び発生します
4

1 に答える 1

0

問題が見つかりました。

2 つの異なる msmq エンドポイントを使用して同じサービスを公開しているため、何らかの奇妙な理由で、SMSvcHost.exe プロセスが同じエンドポイントを 2 回アクティブにします。

解決策を記載した投稿を書きました: http://blog.jorgef.net/2011/07/msmqexception.html

お役に立てば幸いです。

ホルヘ

于 2011-07-20T04:51:16.363 に答える