JMS无法使用来自oracle队列的消息

时间:2014-06-02 15:20:56

标签: java oracle jms

我必须异步地将一些文件从我的系统A推送到系统B.为此我创建了一个JMS Consumer。使用oracle中的enqueue存储过程成功在队列中创建条目。我的消费者应阅读该消息并将其发送给系统B.

这是我的听众代码

public class DMSCustomMessageListener extends DefaultMessageListenerContainer{
      protected MessageConsumer createConsumer(Session session, Destination destination)
        throws JMSException
      {
        return ((AQjmsSession)session).createConsumer(destination, 
          getMessageSelector(), 
          DMS_Master_Type.getORADataFactory(), null, isPubSubNoLocal());
      }
}


public class DMSListener implements FactoryBean{
      private ConnectionFactory connectionFactory;
      private String queueName;
      private String queueUser;

      @Required
      public void setConnectionFactory(QueueConnectionFactory connectionFactory)
      {
        System.out.println("set connection");
        this.connectionFactory = connectionFactory;
      }
      @Required
      public void setQueueName(String queueName) {
        System.out.println("set DMS listener queuename");
        this.queueName = queueName;
      }
      @Required
      public void setQueueUser(String queueUser) {
        System.out.println("set DMS listener queueuser");
        this.queueUser = queueUser;
      }

      public Object getObject() throws Exception
      {
        QueueConnectionFactory qconn = (QueueConnectionFactory)this.connectionFactory;
        AQjmsSession session = (AQjmsSession)qconn.createQueueConnection("score", "score").createQueueSession(true, 0);
        return session.getQueue(this.queueUser, this.queueName);
      }

      public Class getObjectType()
      {
        return Queue.class;
      }

      public boolean isSingleton() {
        return false;
      }
}

以下是我如何配置它。

<bean id="messageDMSListener" class="com.test.DMSTextListener">
</bean>
<bean id="testDMS" class="com.test.DMSListener">
    <property name="connectionFactory" ref="aqConnectionFactoryRspm"/>
    <property name="queueName" value="RSPM_PEND_REQ_Q_DMS"/>    
    <property name="queueUser" value="score"/>
</bean>
<bean id="jmsDMSContainer" class="com.test.DMSCustomMessageListener">
    <property name="connectionFactory" ref="aqConnectionFactoryRspm"/>
    <property name="destination" ref="testDMS"/>
    <property name="messageListener" ref="messageDMSListener" />
    <property name="sessionTransacted" value="true"/>
    <property name="errorHandler" ref="listenerErrorHandler"/>   
</bean>

在我的队列表/视图(AQ$RSPM_PEND_REQ_Q_DMS)中,我将到期原因称为'MAX_RETRY_EXCEEDED'。我已将其配置为10。

可能的原因是什么?请帮助。

1 个答案:

答案 0 :(得分:0)

Oracle数据库队列系统与常见的JMS系统不同,所以与它的对话方式也是如此。 我假设您可以与队列进行通信,但消息不会从队列中消失,而是会过期。如果是这种情况,那么我认为您的队列配置为“多用户”类型。在这种情况下,它不会消失,直到所有收件人都收到消息并且队列所有者也是收件人。因为您只想将消息传递给另一个系统,所以将队列重新配置为单个用户,并且消息在读取后立即消失。

事实上,你也不需要你的java bean。您可以通过直接在数据库中配置队列传播(和相应的作业)来完成这项工作,而无需任何外部对象(下面的示例框架不是完整的解决方案):

BEGIN
DBMS_AQADM.SCHEDULE_PROPAGATION (
   queue_name         => 'init_queue',
   destination        => NULL,
   start_time         => SYSDATE,
   duration           => NULL,
   next_time          => NULL,
   latency            => 60,
   destination_queue  => 'dest_queue');
END;