問題描述
JMS API 不能瀏覽消息,IBM API 可以 (JMS API cannot browse messages, IBM API can)
我當前的應用程序邏輯使用“PROCESS”WMQ 隊列的深度來確定 IIB9 工作流是否正在處理作業。如果工作流正在處理消息,則應用程序會等待該工作流結束。工作流結束後,“PROCESS”隊列將使用 GET 操作清空,應用程序將按順序發送其他消息進行處理。我正在使用 JMS 選擇器來區分工作流並行處理的多條消息。
問題在於確定隊列的深度。JMS API 將深度設為 0,而 IBM API 將深度設為 1(這是預期的)。不幸的是,我不能使用 IBM API 作為我的邏輯,使用一些複雜的消息選擇器。
有沒有人見過這種奇怪的行為?請注意,在進行大小檢查時,IIB9 工作流程正在進行中。是否有需要調整的設置?
JMS 代碼(為清楚起見刪除了消息選擇器):
public class QDepthJMS {
public static void main(String[] a) throws Exception {
MQConnectionFactory factory = new MQConnectionFactory();
factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
factory.setQueueManager("QM01");
factory.setHostName("10.10.98.15");
factory.setPort(1414);
factory.setChannel("Java.Clients");
MQConnection connection = (MQConnection) factory.createConnection();
connection.start();
MQSession session = (MQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("queue:///PROCESS");
MQQueueBrowser browser = (MQQueueBrowser) session.createBrowser(queue);
Enumeration<Message> msgs = browser.getEnumeration();
int count =0;
if (msgs.hasMoreElements()) {
msgs.nextElement();
++count;
}
System.out.println(count);
}
}
IBM API (檢查MQ隊列深度):
public class QDepth {
private final String host;
private final int port;
private final String channel;
private final String manager;
private final MQQueueManager qmgr;
public QDepth(String host, int port, String channel, String manager) throws MQException {
this.host = host;
this.port = port;
this.channel = channel;
this.manager = manager;
this.qmgr = createQueueManager();
}
public int depthOf(String queueName) throws MQException {
MQQueue queue = qmgr.accessQueue(queueName, MQC.MQOO_INQUIRE | MQC.MQOO_INPUT_AS_Q_DEF, null, null, null);
return queue.getCurrentDepth();
}
@SuppressWarnings("unchecked")
private MQQueueManager createQueueManager() throws MQException {
MQEnvironment.channel = channel;
MQEnvironment.port = port;
MQEnvironment.hostname = host;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
return new MQQueueManager(manager);
}
public static void main(String[] a) throws Exception {
QDepth qd = new QDepth("10.10.98.15, 1414, "Java.Clients", "QM01");
System.out.println(qd.depthOf("PROCESS"));
}
}
參考解法
方法 1:
You are not comparing "like with like" ‑ The IBM API queries the queue depth, ie how many messages are in the queue but the JMS API is browsing through the messages and counting them. There is a valid reason for them to be different ‑ the usual cause is that someone has put a message under a unit of work (syncpoint) and it has not yet been committed ‑ Therefore at the point you run the IBM API it will say there's 1 message on the queue (there is...) but it is not gettable / browseable as its not yet committed.
You can verify this using runmqsc (and probably the GUI) by runmqsc DIS QSTATUS and look at the UNCOM attribute ‑ See http://www‑01.ibm.com/support/docview.wss?uid=swg21636775