1

他の 3 つのワーカー エンドポイントを持つディストリビューターとして機能するエンドポイントがあります。受信したメッセージの処理エンドポイントは、トランザクションを開き、一部の xml データを SQL データベースにインポートしようとします。このプロセス中に何らかの例外がスローされた場合、例外がキャッチされ、トランザクションがロールバックされ、xml データがエラー フォルダーに書き込まれます。単純化すると、次のようになります。

public void Handle(doSomethingCmd message)
        {
            System.Data.SqlClient.BeginTransaction();

            try
            {
                //... some xml data import
                throw new Exception();
               //Commit if succeded
            }
            catch (Exception exception)
            {
                System.Data.IDbTransaction.Rollback();
                //...Write file to error folder
            }
        }

そもそも、トランザクションのロールバック後に再試行は行われません。しかし、メッセージが再度送信されると、すべてのワーカー エンドポイント (ワーカーのみ) で例外が発生し (トランザクションを登録できず、メッセージをコントロール キューに送信できませんでした --> 以下のスタック トレースを参照)、nservicebus はメッセージを再試行します (これにより、エラーフォルダにファイルが複数回出現する場合) 分散トランザクションが無効な状態のようです。例外を引き渡す (例外を再スローする) ことができるので、nservicebus がロールバックを処理しますが、その場合、ファイルはエラー フォルダーにも数回書き込まれます (再試行メカニズムのため)。

Failed raising  finished message processing event.|NServiceBus.Unicast.Queuing.FailedToSendMessageException: Failed to send message to address: someEndpoint.distributor.control@SRVPS01 ---> System.Messaging.MessageQueueException: Cannot enlist the transaction.
   at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
   at System.Messaging.MessageQueue.Send(Object obj, MessageQueueTransactionType transactionType)
   at NServiceBus.Transports.Msmq.MsmqMessageSender.Send(TransportMessage message, Address address) in c:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Transports\Msmq\MsmqMessageSender.cs:line 49
   --- End of inner exception stack trace ---
   at NServiceBus.Transports.Msmq.MsmqMessageSender.ThrowFailedToSendException(Address address, Exception ex) in c:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Transports\Msmq\MsmqMessageSender.cs:line 88
   at NServiceBus.Transports.Msmq.MsmqMessageSender.Send(TransportMessage message, Address address) in c:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Transports\Msmq\MsmqMessageSender.cs:line 75
   at NServiceBus.Distributor.MSMQ.ReadyMessages.ReadyMessageSender.SendReadyMessage(String sessionId, Int32 capacityAvailable, Boolean isStarting) in c:\BuildAgent\work\c3100604bbd3ca20\src\NServiceBus.Distributor.MSMQ\ReadyMessages\ReadyMessageSender.cs:line 62
   at NServiceBus.Distributor.MSMQ.ReadyMessages.ReadyMessageSender.TransportOnFinishedMessageProcessing(Object sender, FinishedMessageProcessingEventArgs e) in c:\BuildAgent\work\c3100604bbd3ca20\src\NServiceBus.Distributor.MSMQ\ReadyMessages\ReadyMessageSender.cs:line 50
   at System.EventHandler1.Invoke(Object sender, TEventArgs e)
   at NServiceBus.Unicast.Transport.TransportReceiver.OnFinishedMessageProcessing(TransportMessage msg) in c:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\Transport\TransportReceiver.cs:line 435
  • NServicebus バージョン: 4.6.0.0
  • キューイング: MSMQ
4

1 に答える 1

2

ワーカーは、メッセージをディストリビューターに送り返すことで、作業単位を終了します。この送信は、既存の分散トランザクションに参加します。発生するエラーは、この新しいトランザクション リソースが、既に失敗しているトランザクションに参加しようとしていることが原因です。何かが分散トランザクションをロールバックとしてマークしました。

これは通常、コードが原因です。データベース操作が何らかの形で失敗しているか、メッセージを処理するトランザクションのタイムアウト制限を超えている可能性があります。(デフォルトは 1 分)

ログをチェックして、ワーカーでメッセージを処理するためにトランザクション タイムアウト制限を超えて使用しているかどうかを確認します。

于 2015-07-27T21:26:46.640 に答える