NServiceBus:无法登记事务(未能将消息发送到审核队列)

NServiceBus:无法登记事务(未能将消息发送到审核队列),nservicebus,distributed-transactions,nservicebus-distributor,Nservicebus,Distributed Transactions,Nservicebus Distributor,我有一个端点,与其他三个工作端点一起作为分发服务器工作。 接收到的消息的处理端点打开一个事务,并尝试将一些xml数据导入sql db。如果在此过程中引发了某个异常,则会捕获该异常,回滚事务,并将xml数据写入错误文件夹。 简而言之,它看起来是这样的: public void Handle(doSomethingCmd message) { System.Data.SqlClient.BeginTransaction(); try

我有一个端点,与其他三个工作端点一起作为分发服务器工作。 接收到的消息的处理端点打开一个事务,并尝试将一些xml数据导入sql db。如果在此过程中引发了某个异常,则会捕获该异常,回滚事务,并将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
            }
        }
首先,事务回滚后不会发生重试。但当消息再次发送时,所有工作端点(仅工作端点)都会出现异常(无法登记事务,无法将消息发送到控制队列-->请参阅下面的stacktrace),nservicebus会重试该消息(这导致该文件在错误文件夹中出现多次) 分布式事务似乎处于无效状态。我可以只处理异常(重新抛出异常),因此nservicebus为我处理回滚,但在这种情况下,文件也会多次写入错误文件夹(由于重试机制)

  • NServicebus版本:4.6.0.0
  • 排队:MSMQ

工作人员通过向分发服务器发送消息来结束其工作单元。此发送将加入现有的分布式事务。您得到的错误是由于此新事务资源试图加入已失败的事务而导致的。某些东西已将分布式事务标记为正在回滚

这通常是由您的代码引起的。您的数据库操作以某种方式失败,或者您处理消息时可能已超过事务超时限制。(默认为一分钟)


检查日志,查看是否正在使用高于事务超时限制的时间来处理工作进程上的消息

我将删除try-catch并让NServiceBus处理其工作单元中的事务。我将在异常处理中显式回滚事务(请参阅伪代码),以便在sql db中具有一致的状态。因为在导入xml数据的过程中,涉及到很多不同表的db写操作。我仍然不想收到错误消息或重试,但我想在异常处理中将错误文件写入输出文件夹。所以这个过程看起来是这样的:1。导入xml数据,如果无法实现导入,则抛出ex 2。抓住前女友(不要把前女友吹到NB)3。在ex处理4中回滚数据库。在ex Handling中写入错误文件我想我必须将实际导入打包到一个新的事务作用域中,该事务作用域不参与NServiceBus(TransactionScopeOption.RequiresNew)
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