确认

时间:2016-08-11 09:18:30

标签: java spring oracle

使用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();在会话上,但消息不是已知的。

1 个答案:

答案 0 :(得分:0)

如果您打算明确确认消息,那么在创建TopicSession时,您将明确将确认模式设置为CLIENT_ACKNOWLEDGE。但是,你需要记住两件事:

  1. 您还明确设置了要交易的主题会话。在 在这种情况下,主题会话将使用本地事务和 确认通常会被忽略。如果你打算 手动管理确认您可能需要查看 交易也是如此。
  2. 如果您使用CLIENT_ACKNOWLEDGE,那么您需要 在管理确认时要小心,否则他们会很快开始积累!
  3. 还有一个很大的警告,如果你使用JTA事务,那么transactedacknowledgeMode参数都会被忽略,因为事务将处理这个沟通方面。

    如果你设置了AUTO_ACKNOWLEDGE,那么对acknowledge()的调用会尝试引用机制来显式发送确认但当然不存在,因此{{1 }}