繁体   English   中英

Windows非WCF服务将事务处理的MSMQ消息移到失败的队列

[英]Windows Non-WCF Service Moving Transacted MSMQ Message to Failed Queue

我有一个在Server 2008上运行的旧版Windows服务,该服务从事务MSMQ队列读取消息。 配置为WCF服务。

我们希望通过捕获自定义异常并将相关消息发送到单独的“失败”或“毒药”队列中,具体取决于抛出的异常类型,从而改进代码(C#4.0)中失败和有毒消息​​的处理。

我无法获取Catch代码以将消息发送到单独的队列-它从原始队列中消失(根据需要!),但未显示在“失败”队列中。

为了测试所有队列,都不需要身份验证,并且将权限设置为允许所有人执行所有操作。

显然有什么缺失或错误,我怀疑这与交易有关,但我看不到。 也许这是我尝试做不到的方式?

任何指导/建议表示赞赏!

我们简化的PeekCompleted事件代码:

 private void MessageReceived(object sender, PeekCompletedEventArgs e)
    {

        using (TransactionScope txnScope = new TransactionScope())
        {
            MyMessageType currentMessage = null;
            MessageQueue q = ((MessageQueue)sender);
            try
            {
                Message queueMessage = q.EndPeek(e.AsyncResult);
                currentMessage = (FormMessage)queueMessage.Body;
                Processor distributor = new Processor();

                Processor.Process(currentMessage); // this will throw if need be

                q.ReceiveById(e.Message.Id);
                txnScope.Complete();
                q.BeginPeek();
            }
            catch (MyCustomException ex)
            {
                string qname = ".\private$\failed";
                if (!MessageQueue.Exists(qname)){
                     MessageQueue.Create(qname , true);
                }
                MessageQueue fq = new MessageQueue(qname){
                    Formatter = new BinaryMessageFormatter()
                };
                System.Messaging.Message message2 = new System.Messaging.Message{
                    Formatter = new BinaryMessageFormatter(),
                    Body = currentMessage,
                    Label = "My Failed Message";
                };
                fq.Send(message2);           //send to failed queue
                q.ReceiveById(e.Message.Id); //off of original queue
                txnScope.Complete();         // complete the trx
                _queue.BeginPeek();          // next or wait
            }
            //other catches handle any cases where we want to tnxScope.Dispose()

编辑:2013年10月8日

休的以下回答使我们走上了正确的道路。 在Catch块内,失败队列已创建为事务性队列

MessageQueue.Create(qname , true);

但是发送需要一个TransactionType参数

fq.Send(message2,MessageQueueTransactionType.Single);

做到了。 谢谢休!

如果消息从您的原始队列中消失,则意味着您的代码已到达第二个作用域。Complete()(在catch块中)。

这意味着问题与您发送到错误队列有关。

我建议您需要将队列创建为事务性队列,因为您是在范围内发送的。

MessageQueue fq = new MessageQueue(qname, true){
    Formatter = new BinaryMessageFormatter()
};

然后,您需要执行事务发送:

fq.Send(message2, Transaction.Current);

看看是否可行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM