同一进程的多个实例正在从oracle队列中提取相同的消息

时间:2018-07-19 07:34:20

标签: oracle queue

DAQS是一个自定义进程,它消耗来自oracle队列costedeventqueue的消息。将有多个DAQS实例在轮询同一队列。 我们的期望是,一旦消息由DAQS处理,就应将其删除,并且其他实例都不应从队列中提取相同的消息。但是,尽管oracle版本相同,但在某些环境中无法使用。

下面是读取队列消息的逻辑。

 while(iContinueFlag  == TRUE)
     {
         strMesg = Cdatabase::instance()->readQueueMessage(iMlen,sMsgQueueName);
         mPrsr.processMessage(msg,iRateStatus,iDomainGroupID,iCopyNumber);
        if (strMesg)
            {
               delete[] strMesg; strMesg = NULL;
                                            }
                if( !messageFromQueue->isNull())
                {
                   messageFromQueue->setNull();
                }
            }

unsigned char * Cdatabase::readQueueMessage(int &iMlen,char* sMsgQName) 
          throw(SQLException)
    {
       Consumer cons(conn);
       cons.setConsumerName("DAQS");
       cons.setPositionOfMessage(Consumer::DEQ_FIRST_MSG);
       cons.setDequeueMode(Consumer::DEQ_REMOVE);
       cons.setWaitTime(Consumer::DEQ_NO_WAIT);

       cons.setQueueName(sMsgQName);
       *messageFromQueue = cons.receive(Message::RAW);
       Bytes msgByte = messageFromQueue->getBytes();
       iMlen = msgByte.length();
       unsigned char* mesg = new unsigned char [iMlen];
       memset (mesg, 0, iMlen);
       msgByte.getBytes(mesg, iMlen, 0, 0);
       return mesg;
}

我们使用以下逻辑创建了队列和订户。

       DBMS_AQADM.CREATE_QUEUE_TABLE(queue_table        => ‘COSTEDEVENTQUEUETAIL’,
                                     multiple_consumers => TRUE,
                                     queue_payload_type => 'RAW',
                                     compatible         => '8.1.3',
                                     sort_list          => 'PRIORITY,ENQ_TIME');

       dbms_aqadm.create_queue(queue_name     => ‘COSTEDEVENTQUEUETAIL’,
                               queue_table    => ‘COSTEDEVENTQUEUETAIL’,
                               retention_time => 0);

       dbms_aqadm.start_queue(queue_name => ‘COSTEDEVENTQUEUETAIL’);

      Q_SUBSC := SYS.AQ$_AGENT('DAQS', NULL, NULL);
      DBMS_AQADM.ADD_SUBSCRIBER(
      'COSTEDEVENTQUEUETAIL',--QUEUE_NAME     IN VARCHAR2,
      Q_SUBSC,--SUBSCRIBER     IN SYS.AQ$_AGENT,
      NULL,--RULE           IN VARCHAR2 DEFAULT NULL,
      NULL,--TRANSFORMATION IN VARCHAR2 DEFAULT NULL
      FALSE,--QUEUE_TO_QUEUE IN BOOLEAN DEFAULT FALSE,
      DBMS_AQADM.PERSISTENT--DELIVERY_MODE  IN PLS_INTEGER DEFAULT DBMS_AQADM.PERSISTENT
      );

有人可以让我知道如何解决此问题吗?

先谢谢了。 G.贾亚斯里

1 个答案:

答案 0 :(得分:1)

我们得到了oracle支持的以下答复。

我们已经报告了一个错误27122131问题-由于条件而导致排队,从而导致了重复消息的出队。可以观察到11.2中引入的出队日志功能(最佳出队)可能会由于内存和磁盘上的冗余消息锁定而导致此问题。

作为一种解决方法,您可以通过启用以下事件将出队行为恢复到11.2之前的队列。

conn /as sysdba 
alter system set events '10852 trace name context forever, level 16384';** 

我们已完成上述设置,并重新启动了该过程的多个实例。我们不再看到此问题。