MDB - how to stop delivering messages?

Discussions

EJB programming & troubleshooting: MDB - how to stop delivering messages?

  1. MDB - how to stop delivering messages? (3 messages)

    I'm using Message Driven Beans with Weblogic 6.1. When using a JMS-consumer it is possible to stop the Queue from delivering messages to the consumer by calling the stop() method on the connection. Is it possible to make the JMS-Queue stop delivering messages to a MDB as it is with an ordinary JMS-Connection?

    I think it is a weakness with MDB that you have no control over when the bean should process messages and when not to. Otherwise they are nice and stable to ┬┤work with.
  2. Hi Christian,

    I see no reason why an MDB wouldn't behave as an ordinary JMS consumer: since an MDB must implement the javax.jms.MessageListener interface, it is a JMS consumer like any other one.

    Have you already tried to call the stop() method on the JMS connection from your MDB? If so, have you found any problems?

    Regards,

    Cris
    cristina at acm dot org
  3. An MDB that conforms with the EJB2.0 spec must not call the stop() method. I don't know if WebLogic in specific supports it (I never tried), but it isn't portable. This rule is listed in subsection 24.2.6:
    "The following methods must not be called by enterprise beans because they may interfere with the connection management by the Container: javax.jms.Connection.setExceptionListener, javax.jms.Connection.stop, javax.jms.Connection.setClientID"

    The reason that the EJB spec doesn't provide a mechanism for accomplishing this is that even if the container stopped delivering messages to a specific instance, it would still deliver messages to other instances, perhaps in different nodes of a cluster. It would be complicated to support a mechanism that allows you to stop message delivery to *all* MDB consumers of a particular topic. There are many transaction/synchronization related issues, which are deemed beyond EJB's scope (atleast in EJB2.0).
    If you just want to stop message delivery to a particular instance (although I can't think of any reason to do so), you can accomplish this by throwing a system exception.

    Gal
  4. Thanks for the answer,

    The reason why I want to stop deliveries to the MDB is that messages should not be processed, if the backend is down. As it is now, the MDB has to roll back the transaction to put the message back on queue if the backend is down. Then the message is redelivered every 15 minutes the next four hours. After that, the message is routed to an error queue. This is a waste of cpu-cycles, and also potentially valid messages will be put on an error queue for error handling.

    I have tried to use an ordinary JMS-consumer, but weblogic seem to have a bug as a JMS-provider. If there are put a lot more messages on the queue than the consumers can consume on the fly, deliverances will stop! In the weblogic console you can see that there are messages on the queue, and there are consumers registered as listeners to the queue, but nothing happens. That is why we are using the MDB, even if it is not the optimum solution. They are working very stable as consumers.

    Does anyone else know of problems with JMS on weblogic. I cannot rule out the possibility that I'm the one with bugs in my code, but the behaviour seems awfully strange to me...