0

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) {
    }       
}
Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
Singh
  • 23
  • 6
  • I don't think there is enough information to answer the question here. It depends on how your bus is configured and the activation specification for receiving messages. For example if you are allowing parallel message delivery to the MDB then you could always see things being out of order, you may just be lucky that without the rollback you are seeing things being done in order. – Alasdair Feb 28 '19 at 18:16
  • @Alasdair I gave some of the settings under activation specification and bus in my question. Please let me know what other information is required. Also the main question is about messages getting blocked and delivery delay after calling setRollbackOnly. – Singh Feb 28 '19 at 18:35
  • @Alasdair The provider of activation specification is Default messaging provider. – Singh Feb 28 '19 at 18:46

0 Answers0