In
non-ASF mode threads are active from the moment that
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 that are available to
be processed. Each active thread is an individual physical network
connection.
If
you are using WebSphere® MQ Version
7.0 or later as your messaging provider, it is possible to have up
to ten threads sharing a single physical network connection.
For WebSphere Application Server Version 7 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 WebSphere Application Server Version 7. For example, if you have an application server cluster with some members at Version 6.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.
Note: The
following message listener service custom properties do not work in
non-ASF mode:
- SERVER.SESSION.POOL.REAP
- SERVER.SESSION.POOL.UNUSED.TIMEOUT
- SERVER.SESSION.POOL.UNUSED.TIMEOUT.Ipaname
The following diagram shows how message processing
takes place between WebSphere Application Server 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:
- When the listener port is started, it gets one thread
from the
message listener service thread pool.
- 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.
- The listener port creates a transaction to manage the
message
processing.
- 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.
- When the message consumer detects a message it checks
whether
the message is suitable for the MDB that is using the listener port.
- If the message is suitable, the receive() method
takes it off the destination and sends it to the thread.
- The
thread invokes the onMessage() method
of the MDB on the message consumer, and the message is processed.
- If the message finishes processing successfully, the transaction
commits. If the message does not process successfully, the transaction
rolls back.
- 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 that the
MDB can only process one message at a time. If you want to process
more than one message concurrently, you 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:
- When the listener
port is started, it gets two threads from the
message listener service thread pool.
- 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.
- Both message
consumers call the receive() method
to listen for messages on the destination. The consumers compete to
get messages from the destination.
- 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, you must make sure that the
value that you specify for the NON.ASF.RECEIVE.TIMEOUT message
listener service custom property is smaller than the value that you
specify for the Total transaction lifetime timeout transaction
service property, and also that the difference between the values
of the two properties is greater than the amount of time that the onMessage() method
of the message-driven bean (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:
- The listener port starts. It allocates
a thread from the thread
pool and creates a transaction and a message consumer on the thread.
- The thread calls the receive() method
to listen for messages.
- After 110 seconds a message appears
at the destination.
- The thread removes the message from the
destination and calls
the onMessage() method of the
MDB to begin processing the message.
- 10 seconds later, the
transaction timeout is reached. The application
server marks the transaction for rollback.
- 5 seconds later,
the onMessage() method
finishes processing the message and tries to commit the transaction.
- 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.