WCF / MQSeries:如何保留有害消息

时间:2011-04-07 14:12:17

标签: .net wcf ibm-mq

我已经设置了一个WebSphere MQ合同。我将队列配置为将一次重试的消息传递到一个单独的队列进行毒性处理。我使用WebSphere MQ v 7.01提供的WCF通道与服务进行交互。

虽然我的服务已连接,但事情仍然完美无缺。一旦服务断开连接,有害消息就会重新出现在主队列中。立即重新启动服务会将消息从主队列放回到毒性队列中。在服务从队列中断开后,我需要做什么才能使消息保留在毒性队列中?

代码目前处于POC模式,因此我在Window上托管服务。该类具有以下属性:

  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
  [AssuredDelivery()]
  public partial class MainWindow : Window, IWmqEndpoint

服务合同是:

  [ServiceContract()]
  public interface IWmqEndpoint
  {
    [OperationContract(IsOneWay = true)]
    void SendMessage(string message);

    [OperationContract(IsOneWay = true)]
    void SendComplex(PersonName name);
  }

主队列是持久的,否则是默认设置。同上毒药队列。

队列设置:

  1. 回退请求队列:wcf.inbound.poison
  2. 退出门槛:5
  3. 哈登退出:没有硬化
  4. NPM类:正常

1 个答案:

答案 0 :(得分:0)

当应用程序读取工作单元内的消息时,WMQ不知道同一工作单元中是否还有其他消息。如果消息结果是有害消息,则WMQ将其重新排队到与其他所有工作相同的工作单元中的退出队列 。如果WMQ要将消息移到工作单元之外,那么它可能会丢失或重复。如果WMQ代表您提交了UOW,那么它有可能提交您已检索但未完全处理的消息。因此,如果执行回退处理,WMQ会使您在工作单元之间明确提交。

您看到的行为听起来像是在同步点下的退出队列中保留的消息。当应用程序关闭时,会发生隐式BACKOUT,并且所有消息都会返回到其原始队列。您至少需要一个成功的工作单元才能使消息保留在退出队列中。尝试在坏的后面的输入队列上放置一条好消息,然后执行一个明确的COMMIT

顺便说一下,WebSphere MQ没有持久队列的概念。持久性是消息的一个属性。队列具有属性DEFPSIST,该属性告诉应用程序在首次创建消息时是否使消息持久化。消息的持久性不会随着它在整个WMQ网络中传播而改变,无论它通过的队列的设置如何。因此,回退队列上的DEFPSIST无效,因为消息持久性是在它到达回退队列之前定义的。