Reputation: 99
I have an MDB listener on an IBM MQ queue in IBM WAS server. MDB receives the message and do the processing and updates the database. These is one problematic scenario that I am unable to handle.
In case when a message arrived at MDB listener and it's middle of processing, if someone forced stop the MDB application or restarts entire server note, the message under process will be lost from the queue without finishing the process. Is there any mechanism to avoid such scenario. I tries to use CLIENT_ACKNOWLEDGEMENT with message.acknowledge() but it didn't work.
My MDB is like this:
@MessageDriven(name = "queueMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
}
public class TestMdb implements MessageListener {
@Resource
private MessageDrivenContext messageDrivenContext;
@Override
public void onMessage(Message message) {
try {
// Some usefull code...
message.acknowledge()
}
catch (Exception e) {
messageDrivenContext.setRollbackOnly();
}
}
}
My ibm-ejb-jar.xml look like below:
<ejb-jar-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_2.xsd"
version="1.0">
<message-driven name="TestMdb">
<jca-adapter activation-spec-binding-name="jms/TestQueueAS" destination-binding-name="jms/TestQueue" />
</message-driven>
</ejb-jar-bnd>
Can anyone please help me solve this issue, If only I get the acknowledgement working, I will acknowledge every message, in case of forced stop, the queue message will not be acknowledged and will not be deleted from actual queue. That message will be processed once the MDB is up again.
Upvotes: 0
Views: 181
Reputation: 402
For Container Managed transactions, there should be no need to acknowledge the message as it will be removed from the queue when the MDB onMessage
method completes. In the event of an exception or failure during normal onMessage
processing, the message will be rolled-back to the queue and the JMSXDeliveryCount
of the message will be incremented. The message will then be consumed by an new MDB instance to retry processing.
In this scenario WAS is coordinating a transaction with IBM MQ and potentially other transactional resources. During MDB processing, WAS is forcibly stopped or the host server is restarted. On recovery, WAS will attempt to replay any 'in-flight transactions' and resolve units of work that have advanced to the initial prepare
phase.
Meanwhile messages on the queue that are considered as being part of a transaction by IBM MQ, but not necessarily considered 'in-flight' by the transactional coordinator, will not visible. There are two environment variables that determine IBM MQ's handling of messages in this state; AMQ_TRANSACTION_EXPIRY_RESCAN
(how often the queue manager should check for transactions marked as expired) and AMQ_XA_TRANSACTION_EXPIRY
(how long the queue manager should wait before marking a transaction as expired), and are described in this documentation. Common values are AMQ_TRANSACTION_EXPIRY_RESCAN=30000
and AMQ_XA_TRANSACTION_EXPIRY=60000
To set these environment variables on the system hosting your queue manager:
export AMQ_TRANSACTION_EXPIRY_RESCAN=30000
export AMQ_XA_TRANSACTION_EXPIRY=60000
Upvotes: 1