Implications of IMS syncpoints
The IBM® MQ classes for JMS build upon the existing IBM MQ adapter support which makes use of ESAF. This means that the documented behavior applies, including all open handles being closed by the IMS adapter when a syncpoint occurs.
See Syncpoints in IMS applications for more information.
To illustrate this point, consider the following code running in a JMP environment. The second
call to mp.send()
results in a JMSException
as the
messageQueue.getUnique(inputMessage)
code results in all open IBM MQ connection and object handles being closed.
Similar behavior is observed if the getUnique()
call was replaced with
Transaction.commit()
, but not if Transaction.rollback()
was
used.
//Create a connection to queue manager MQ21.
MQConnectionFactory cf = new MQConnectionFactory();
cf.setQueueManager("MQ21");
Connection c = cf.createConnection();
Session s = c.createSession();
//Send a message to MQ queue Q1.
Queue q = new MQQueue("Q1");
MessageProducer mp = s.createProducer(q);
TextMessage m = s.createTextMessage("Hello world!");
mp.send(m);
//Get a message from an IMS message queue. This results in a GU call
//which results in all MQ handles being closed.
Application a = ApplicationFactory.createApplication();
MessageQueue messageQueue = a.getMessageQueue();
IOMessage inputMessage = a.getIOMessage(MESSAGE_CLASS_NAME);
messageQueue.getUnique(inputMessage);
//This attempt to send another message will result in a JMSException containing a
//MQRC_HCONN_ERROR as the connection/handle has been closed.
mp.send(m);
The correct code to use in this scenario is as follows. In this case the connection to IBM MQ is closed prior to calling
getUnique()
.
The connection and session are then recreated in order to send another
message.
//Create a connection to queue manager MQ21.
MQConnectionFactory cf = new MQConnectionFactory();
cf.setQueueManager("MQ21");
Connection c = cf.createConnection();
Session s = c.createSession();
//Send a message to MQ queue Q1.
Queue q = new MQQueue("Q1");
MessageProducer mp = s.createProducer(q);
TextMessage m = s.createTextMessage("Hello world!");
mp.send(m);
//Close the connection to MQ, which closes all MQ object handles.
//The send of the message will be committed by the subsequent GU call.
c.close();
c = null;
s = null;
mp = null;
//Get a message from an IMS message queue. This results in a GU call.
Application a = ApplicationFactory.createApplication();
MessageQueue messageQueue = a.getMessageQueue();
IOMessage inputMessage = a.getIOMessage(MESSAGE_CLASS_NAME);
messageQueue.getUnique(inputMessage);
//Recreate the connection to MQ and send another message;
c = cf.createConnection();
s = c.createSession();
mp = s.createProducer(q);
m = s.createTextMessage("Hello world 2!");
mp.send(m);