I am implementing an JMS MDB solution for invoking webservices that would be triggered from several points in the application. For the sake of validating my solution I am just passing Integer
objects right now. I am forcing the code to redeliver messages when the Integer
is greater than 5
. However, if the message has been redelivered twice it should be ignored/commit. The wait time configured in Websphere is 5 mins, and the max failed deliveries per message is 0 (under Exception destination on Buses -> {bus} -> Destinations -> {destination}).
The problem is when message for object 6
is sent back to queue for re-delivery after 5 mins, the messages for 7, 8, 9... are also put on hold until 6
is redelivered. Although I know JMS does not guarantees message delivery order, but usually it is FIFO. But once a message has been sent back to the queue and redelivered, the order of remaining messages is not sequential. i.e. it is something like 6, 8, 9, 7.
Under JMS Activation specifications Maximum batch size is 1 and Maximum concurrent MDB invocations per endpoint is 10.
Any idea how to deal with new messages that are blocked due to message on hold? I referred the question at this link, it says that the queue should not be blocked.
JMS and MDB with setRollbackOnly
Also please provide suggestions on maintaining message order.
Snippet of code:
public void onMessage(javax.jms.Message msg) {
try {
if (msg instanceof ObjectMessage) {
ObjectMessage objMsg = (ObjectMessage)msg;
Object obj = objMsg.getObject();
UserTransaction userTxn = getMessageDrivenContext().getUserTransaction();
userTxn.begin();
InitialContext initialContext = new InitialContext();
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("jms/cf");
javax.jms.Connection conn = cf.createConnection();
Session jmsSession = conn.createSession(true, -1);
Queue queue = (Queue) initialContext.lookup("jms/queue1");
QueueBrowser queueBrowser = jmsSession.createBrowser(queue);
Enumeration enumeration = queueBrowser.getEnumeration();
while (enumeration.hasMoreElements()) {
System.out.println("Browse [" + enumeration.nextElement() + "]");
}
if ((Integer)obj >= 6) {
int count = Integer.valueOf(msg.getStringProperty("JMSXDeliveryCount"));
if (count > 2) {
System.out.println("********** max rollback");
userTxn.commit();
} else {
System.out.println("********** rollback");
userTxn.setRollbackOnly();
}
} else {
System.out.println("********** commit");
userTxn.commit();
}
} else {
}
} catch (Exception ex) {
ex.printStackTrace();
throw new EJBException("Transaction failed: " + ex.getMessage());
} catch (Throwable t) {
}
}