This is a fundamental knowledge of JMS / messaging.
Queues implement "load balancing" scenarios, through which a message enters a queue and is processed by a single consumer. An increase in the number of consumers increases the potential throughput of this queue processing. Each message in the queue will be processed by one and only one user.
Topics provide the semantics of publishing-subscribing: all topic users will receive a message that will be clicked on this topic.
With this in mind, when a message is canceled and transmitted (transactionally) to the consumer, it in no way blocks the remainder of the queue if it is asynchronous (as is the case with MDB).
As the Java EE Tutorial states:
Message consumption
Messaging products are inherently asynchronous: there is no fundamental time relationship between the production and consumption of a message. However, the JMS specification uses this term in a more precise sense. Messages can be used in two ways:
Synchronously: the subscriber or recipient explicitly retrieves the message from the recipient, invoking the receiving method. The receiving method may be blocked until the message arrives or there is no timeout if the message does not arrive within the specified period.
Asynchronously: the client can register a message listener with the consumer. A message listener is similar to an event listener. Whenever a message arrives at its destination, the JMS provider delivers the message by calling the listeners onMessage method, which acts on the contents of the message.
Because you are using a MessageListener
, which is by definition asynchronous , you are not blocking the queue or its subsequent processing.
Also from the tutorial is the following:
Using a Beans Session to Create and Receive Messages Synchronously
An application that creates messages or receives them synchronously can use a bean session to perform these operations. An example in an application that uses the JMS API with a bean session uses a non-bean session to post messages to a topic.
Since blocking synchronous reception links server resources, it is not recommended to use such a receiving call in a bean. Instead, use synchronous time reception, or use a receive bean to receive messages asynchronously. For more information about blocking and synchronized reception with synchronization, see "Recording Clients for an Example of Synchronous Reception."
Regarding message failure, it depends on how your queue is configured. You can set error queues (in the case of containers such as Glassfish or Weblogic) that could not be sent to messages for later monitoring. In your case, you use setRollbackOnly
which is processed this way :
7.1.2 Encoding of Message-Driven Bean: MessageBean.java
The message-driven bean class, MessageBean.java, implements the methods setMessageDrivenContext, ejbCreate, onMessage, and ejbRemove. The onMessage method, almost identical to the TextListener.java method, sends an incoming message to TextMessage and displays the text. the only significant difference is that it calls the MessageDrivenContext.setRollbackOnly method in case of an exception. This method rolls back the transaction so that the message is re-delivered.
I recommend that you read the Java EE tutorial, as well as Enterprise Integration Patterns , which details messaging concepts as well as agnostic product / technology.