【发布时间】: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".