【问题标题】:Spring oracle advanced queue nullpointer on acknowledgeSpring oracle 高级队列空指针确认
【发布时间】:2016-08-11 19:10:33
【问题描述】:

使用 spring 将消息从 Oracle 高级队列中出列,我收到 ADT 消息,但在确认时出现空指针。有什么建议吗?

public class OracleAQTopicConnectionFactory {

private DataSource dataSource;

/**
 *
 * @return -
 * @throws Exception -
 */
public TopicConnectionFactory createConnectionFactory() throws Exception {
    return oracle.jms.AQjmsFactory.getTopicConnectionFactory(dataSource);
}

/**
 *
 * @param dataSource -
 */
public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}
}


public class OracleAQTopicDestinationFactory implements FactoryBean {

private static final org.apache.log4j.Logger LOGGER
        = org.apache.log4j.Logger.getLogger(OracleAQTopicDestinationFactory.class);

private TopicConnectionFactory connectionFactory;
private String queueUser;
private String queueName;

/**
 *
 * @return @throws Exception
 */
public Object getObject() throws Exception {

    TopicConnection topicConnection = connectionFactory.createTopicConnection();
    TopicSession topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
    LOGGER.info("Acknowledge Mode: " + topicSession.getAcknowledgeMode());
    return ((AQjmsSession) topicSession).getTopic(queueUser, queueName);
}

/**
 *
 * @return -
 */
public Class getObjectType() {
    return javax.jms.Topic.class;
}

/**
 *
 * @return -
 */
public boolean isSingleton() {
    return false;
}

/**
 *
 * @param connectionFactory -
 */
public void setConnectionFactory(TopicConnectionFactory connectionFactory) {
    this.connectionFactory = connectionFactory;
}

/**
 *
 * @param queueUser -
 */
public void setQueueUser(String queueUser) {
    this.queueUser = queueUser;
}

/**
 *
 * @param queueName -
 */
public void setQueueName(String queueName) {
    this.queueName = queueName;
}
}

public class OracleObjectMessageListenerContainer extends DefaultMessageListenerContainer {

private String subscriberName;

/**
 *
 * @param subscriberName -
 */
public void setSubscriberName(String subscriberName) {
    this.subscriberName = subscriberName;
}

/**
 *
 */
public OracleObjectMessageListenerContainer() {
    super();
}

/**
 *
 * @param session -
 * @param destination -
 * @return -
 * @throws JMSException -
 */
@Override
protected MessageConsumer createConsumer(Session session, Destination destination) throws JMSException {
    return ((AQjmsSession) session).createDurableSubscriber((Topic) destination,
            subscriberName, Sync.getORADataFactory());
}

}



public class OracleNotificationListener implements MessageListener {

private static final org.apache.log4j.Logger LOGGER
        = org.apache.log4j.Logger.getLogger(OracleNotificationListener.class);

@Override
public void onMessage(Message message) {
    try {

        AQjmsAdtMessage msg = (AQjmsAdtMessage) message;
        Sync sync = (Sync) msg.getAdtPayload();
        if (new DestinationHandler().messageHandler(sync)) {
            msg.acknowledge();
        }

    } catch (JMSException ex) {
        LOGGER.error("JMSException: " + ex.getMessage());
    }
}
}

在 msg.acknowledge();我得到以下信息:

java.lang.NullPointerException
at oracle.jms.AQjmsMessage.acknowledge(AQjmsMessage.java:2036)

我也试过 commit();在会话中,但消息未被确认。

【问题讨论】:

  • 确认分为三种。 AUTO_ACKNOWLEDG、CLIENT_ACKNOWLEDGE、DUPS_OK_ACKNOWLEDGE。你已经设置了第一个。在这种情况下,确认是自动完成的。
  • AUTO_ACKNLOWLEDGE 不确认消息,无论是在 toppicsession 上的提交还是会话确认消息,它都保留在队列中,使用 plsql 将消息出列也保留在队列中。
  • 保留栏里有什么? select name, retention from dba_queues where name = "q_name".

标签: java spring oracle


【解决方案1】:

如果您的意图是显式确认消息,那么您将在创建 TopicSession 时显式将确认模式设置为 CLIENT_ACKNOWLEDGE。但是,您需要记住两点:

  1. 您还明确设置了要处理的主题会话。在 在这种情况下,主题会话将使用本地事务,并且 确认大多会被忽略。如果你打算 手动管理确认,您可能需要查看 交易也是如此。
  2. 如果您使用 CLIENT_ACKNOWLEDGE,那么您需要 在管理确认时要小心,否则它们会很快开始积累!

还有一个重要的警告是,如果您使用的是 JTA 事务,那么 transactedacknowledgeMode 参数都会被忽略,因为事务将处理这方面的通信。

如果您设置了 AUTO_ACKNOWLEDGE,那么对acknowledge() 的调用将尝试引用显式发送确认的机制,但当然不存在,因此null pointer exception

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2015-08-10
    • 2010-09-07
    • 1970-01-01
    • 2016-01-20
    相关资源
    最近更新 更多