WAS v8.5 > WebSphere applications > Messaging resources > Message-driven beans - automatic message retrieval > Message processing in ASF mode and non-ASF mode

How messages are processed in non-ASF mode

In non-ASF mode threads are active from the moment the listener port is started. The number of active threads is dictated by the value specified for Maximum Sessions. The number of threads specified in Maximum Sessions are active, regardless of the number of messages available to be processed. Each active thread is an individual physical network connection.

If we are using WebSphere MQ v7.0 or later as your messaging provider, it is possible to have up to ten threads sharing a single physical network connection.

For WAS v7 and later, listener ports are stabilized. For more information, read the article on stabilized features. You should plan to migrate your WebSphere MQ message-driven bean deployment configurations from using listener ports to using activation specifications. However, you should not begin this migration until you are sure the application does not have to work on application servers earlier than WAS v7. For example, if we have an application server cluster with some members at v6.1 and some at a later version, you should not migrate applications on that cluster to use activation specifications until after you migrate all the application servers in the cluster to the later version.


Message processing in non-ASF mode

You activate non-ASF mode by specifying a non-zero value for the NON.ASF.RECEIVE.TIMEOUT message listener service custom property. NON.ASF.RECEIVE.TIMEOUT acts as a switch that turns off ASF mode, and also as a timeout value for the receive() method.

The following message listener service custom properties do not work in non-ASF mode:

The following diagram shows how message processing takes place between WAS and WebSphere MQ in non-ASF mode:

Figure 1. Message processing in non-ASF mode

As shown in the diagram, when the message listener service is operating in non-ASF mode, messages are processed in the following way:

  1. When the listener port is started, it gets one thread from the message listener service thread pool.
  2. The listener port opens a connection to the WebSphere MQ queue manager on the thread and creates a JMS message consumer. The message consumer listens to the JMS destination which the listener port is configured to listen to.
  3. The listener port creates a transaction to manage the message processing.
  4. The thread calls the receive() method on the message consumer to listen for messages at the destination. If the receive() method does not detect a message in the time specified for NON.ASF.RECEIVE.TIMEOUT, the application server rolls back the active transaction and starts a new one. The thread then starts calling the receive() method again.

  5. When the message consumer detects a message it checks whether the message is suitable for the MDB that is using the listener port.

  6. If the message is suitable, the receive() method takes it off the destination and sends it to the thread.
  7. The thread invokes the onMessage() method of the MDB on the message consumer, and the message is processed.

  8. If the message finishes processing successfully, the transaction commits. If the message does not process successfully, the transaction rolls back.
  9. A new transaction is started and the message consumer calls the receive() method to listen for new messages.

The number of threads that an MDB can process concurrently is determined by the value of the Maximum Sessions property for the listener port. If you set Maximum Sessions to the default value of 1, this means the MDB can only process one message at a time. To process more than one message concurrently, we can do this in ASF mode by setting Maximum Sessions to a value higher than 1. For example, if you set Maximum Sessions to 2, messages are processed in the following way:

  1. When the listener port is started, it gets two threads from the message listener service thread pool.
  2. The listener port creates a message consumer and a transaction on each thread. The message consumers listen to the destination which the listener port is configured to listen to.
  3. Both message consumers call the receive() method to listen for messages on the destination. The consumers compete to get messages from the destination.

  4. When one of the consumers successfully retrieves the message, it processes it by calling the onMessage() method of the MDB. The other message consumer keeps on calling the receive() method to listen for messages on the destination.


How to avoid unwanted transaction timeouts

If your messaging system is running in non-ASF mode, to avoid unwanted transaction timeouts, you must allow a sufficient amount of time for processing to be completed before the total transaction lifetime timeout is reached. Therefore, verify the value specified for the NON.ASF.RECEIVE.TIMEOUT message listener service custom property is smaller than the value specified for the Total transaction lifetime timeout transaction service property, and also the difference between the values of the two properties is greater than the amount of time the onMessage() method of the MDB takes to process the message.

As the following example shows, if these properties are not correctly configured, transactions can time out before they are completed. This is because the thread begins calling the receive() method as soon as the transaction is created. In the following example, NON.ASF.RECEIVE.TIMEOUT is set to 110000 milliseconds (110 seconds), Total transaction lifetime timeout is set to 120 seconds and the onMessage () method of the MDB takes 15 seconds to process a message. The example supposes that a message does not appear at the destination until the receive() method has almost timed out:

  1. The listener port starts. It allocates a thread from the thread pool and creates a transaction and a message consumer on the thread.
  2. The thread calls the receive() method to listen for messages.
  3. After 110 seconds a message appears at the destination.
  4. The thread removes the message from the destination and calls the onMessage() method of the MDB to begin processing the message.
  5. 10 seconds later, the transaction timeout is reached. The application server marks the transaction for rollback.
  6. 5 seconds later, the onMessage() method finishes processing the message and tries to commit the transaction.
  7. The total amount of time that has elapsed since the transaction was started is 125 seconds (110 seconds waiting for a message, plus 15 seconds to process the message). As this is longer than the transaction timeout, the application server prevents the transaction from being committed, and it is rolled back.

For further information about how to configure the NON.ASF.RECEIVE.TIMEOUT and Total transaction lifetime timeout properties to avoid unwanted transaction time outs, see the related tasks.


Related concepts:

Strict message ordering using non-ASF listener ports


Related


Configure transaction properties for an application server
Avoiding transaction timeouts in non-ASF mode


Reference:

Message listener service custom properties
WebSphere MQ messaging provider connection factory settings
WebSphere MQ messaging provider queue connection factory settings
WebSphere MQ messaging provider topic connection factory settings
Listener port settings
Stabilized features


+

Search Tips   |   Advanced Search