ニキータソコロフ:
私は、JMS経由でIBMキューからメッセージを配信モードを認める使用したいです。
だから、私はこの方法でコンテキストを設定します。
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();
}
ここでは、特別なパラメータは次のとおりです。
cf.setIntProperty(WMQConstants.ACKNOWLEDGE_MODE, WMQConstants.CLIENT_ACKNOWLEDGE);
コードのロジックでは、私はメッセージを処理するメッセージリスナを使用します。
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
}
}
});
今、このコードは動作しません:データベースに障害が発生した場合、メッセージは失われます。私たちは、JMSブラウジングを経由して、それを見つけることができません。どうして?
シャシ:
コンテキストを作成するときには、sessionModeパラメータを使用していません。私の知る限りでは指定せずに作成されたコンテキストがsessionMode
同じであるAUTO_ACKNOWLEDGE
、それはアプリケーションに配信された後、JMSクライアントが自動的にメッセージを確認する場所。だからあなたのケースのためにあなたが使用する必要があります。
cf.createContext(JMSContext.CLIENT_ACKNOWLEDGE);
私が試したし、それは私のために動作しますが、場合を意味しmessage.acknowlege()
、同じメッセージが再度配信され、呼び出されません。