Reputation: 55
I want to use acknowledge mode in delivering messages from ibm queue via JMS.
So, I configure context in this way:
private JMSContext createJmsContext() throws JMSException {
JmsConnectionFactory cf;
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
cf = ff.createConnectionFactory();
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, props.getProperty(Q_HOST));
cf.setIntProperty(WMQConstants.WMQ_PORT, Integer.valueOf(props.getProperty(Q_PORT)));
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, props.getProperty(Q_CHANNEL));
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, props.getProperty(Q_MANAGER));
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setIntProperty(WMQConstants.ACKNOWLEDGE_MODE, WMQConstants.CLIENT_ACKNOWLEDGE);
return cf.createContext();
}
Here is special parameter:
cf.setIntProperty(WMQConstants.ACKNOWLEDGE_MODE, WMQConstants.CLIENT_ACKNOWLEDGE);
In code logic I use message listener which processes messages:
consumer.setMessageListener(message -> {
try {
// business logic
message.acknowledge();
} catch (Throwable e) {
try {
// saving unsuccessful message to special database
} catch (Throwable e) {
// if database does not work, we want message to return back to queue and try process it again when database will work
sleep(60_000); // to prevent too many process requests, there is only one working thread, so we can pause it
}
}
});
Now this code does not work: if database fails, message will be lost. We can not find it via JMS browsing. Why?
Upvotes: 2
Views: 600
Reputation: 15263
You are not using sessionMode parameter when creating context. As far as I know a context created without specifying sessionMode
is same as AUTO_ACKNOWLEDGE
where JMS client will automatically acknowledge message after it is delivered to application. So for your case you will need to use:
cf.createContext(JMSContext.CLIENT_ACKNOWLEDGE);
I tried and it works for me, meaning if message.acknowlege()
is not called, the same message is delivered again.
Upvotes: 3