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

本文关键字:移动 消息 失败 队列 MSMQ WCF 服务 事务处理 Windows | 更新日期: 2023-09-27 18:34:23

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

我们希望通过捕获自定义异常并根据引发的异常类型将相关消息发送到单独的"失败"或"有害"队列来改进代码 (C# 4.0( 中失败消息和有害消息的处理。

我无法获取 Catch 代码将消息发送到单独的队列 - 它从原始队列中消失(如愿以偿!(,但没有显示在"失败"队列中。

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

显然有些东西丢失或错误,我怀疑它与交易有关,但我看不到它。或者也许这是不可能的,我想这样做?

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

简化的速览完成事件代码:

 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()

编辑 : 十月 8, 2013

休在下面的回答让我们走上了正确的轨道。在 Catch 块中,失败队列已创建为事务性队列

MessageQueue.Create(qname , true);

但发送需要事务类型参数

fq.Send(message2,MessageQueueTransactionType.Single);

这就成功了。谢谢休!

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

如果消息从原始队列中消失,则意味着您的代码正在到达第二个范围。Complete(( (在你的 catch 块中(。

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

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

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

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

fq.Send(message2, Transaction.Current);

看看这是否有效。