JMS redelivery
Hi,
New to WLi and have a concern over the issue of JMS redelivery - this has been posted before but no answer given so hopefully someone knows...
Creating a JMS event generator and having a process that picks up the event goes through a channel, but if the message cannot be processed how do you ensure that the no-acknowledgement/exception is thown back to the queue so that redelivery can take place? Can the channel do this or is there no way of handling this situation?
Or do you just write an MDB for the queue and have that MDB call the process?
Thanks if you can help!
To rollback message using JMS EG. You need to create Sync. Subcription process. Handle global exception handler that rethrows the exception. You should also configure JMS queue and error queue. Cofigure JMS queue redelivery threshholds. Number of time to try to redeliver and message expiry.
Similar Messages
-
Best way to configure redelivery limit value for a Queue
Hello,
My doubt is related to configuring the JMS Redelivery Limit property from Weblogic 9.2 Server.
We must support redelivery attempts in our queue, with a redelivery delay of 30s. So, we have set the queue's Redelivery Limit property to -1, via Console Configuration:
Settings for My_DQueue -> Delivery Failure -> Redelivery Limit = -1
The consumer of that queue is a MDBBean, which extends org.springframework.ejb.support.AbstractJmsMessageDrivenBean.
The producers to that queue are weblogic.jms.extensions.WLMessageProducer.
That queue has an error queue configured as Error Destination.
Then, the WLMessageProducer is the one who specifies that value:
WLMessageProducer messageProducer = (WLMessageProducer)queueSession.createProducer(queue);
messageProducer.setRedeliveryLimit(5);However, we will not be able to ensure that all message producers pointing that queue will specifiy that redelivery limit. This may lead us to problems, as default queue Redelivery Limit is set to -1, and messages without specified redelivery limit would be redelivered indefinitely.
I'd like to know if there is any way to specify a MAXIMUM redelivery limit value for a JMS queue. For example: fixing that limit to 10. If producers specify by themselves a redelivery limit lower than such value, that limit is applied to messages. Otherwise, the configured default limit value is used.
Another option we have considered is to include, in the MDB's onMessage() method, a validation of the "JMS_BEA_RedeliveryLimit" message property:
This validation would check whether no redelivery limit is configured in the Producer, and would forward such messages directly to the error queue, from the MDB, when the "JMSXDeliveryCount" outnumbers our fixed value:
public void onMessage(Message message) {
try {
if(message.getIntProperty("JMS_BEA_RedeliveryLimit")<0){
//MESSAGE FOUND WITHOUT REDELIVERY LIMIT SPECIFIED BY PRODUCER.
//POTENTIAL DANGER OF BEING REDELIVERED INDEFINETELY
int deliveryCount = message.getIntProperty("JMSXDeliveryCount");
if(deliveryCount>10){
//CAN I FORWARD MESSAGE TO ERROR DESTINATION?But we were not able to found such examples to achieve this
Thanks in advance!
Joan EsteveHi Joan,
I just double-checked, and as far as I can tell the options for setting a redelivery limit include programmatically on the Producer or by configuring an override on the Destination. Unfortunately, you need the override to only take effect if the delivery limit hasn't already been set. (If we had a default deliverylimit configurable on our connection factory, this would have done the trick.)
I think you've already hit upon the solution: your consumers can check each received message's JMSXDeliveryCount and act accordingly. It's fine for a consumer to use the JMS_BEA_RedeliveryLimit property see if the Limit has been set by a producer, and then check JMSXDeliveryCount to check the delivery count, but I'm not sure if the JMS_BEA_RedeliveryLimit property is set in older versions (8.1 may not have it for example).
As a refinement, you may want to use the WLMessageProducer forward() API. This is an alternative to send() that preserves the message-id and timestamp of a consumed message. I don't think forward() allows any modification of the consumed message before it's forwarded.
Hope this helps,
Tom
Edited by: Tom B on Feb 22, 2013 10:03 AM -
Handle exception onMessage()
Here is the situation.
1. MDB is configured for a JMS Queue.
2. Inside the onMessage(), a call is made to business logic
which invokes a series of Java classes.
3. Now there is a run time Exception somewhere deep in this
business logic classes.
4. This exception is caught in onMessage().
I would like to throw a new exception in order to escalate the error
on the top level.
5. The container catches the runtime Exception and loop 3times in order to redeliver
the
message.
Question: How to throw a new runtime exception on top level?
I'm using WebLogic 7.0 SP2
Any input on this problem is greatly appreciated.
Thanks,
Gurcan
Throwing any RuntimeException or Error within
onMessage() forces
a rollback() for transactional MDBs, and a recover()
for non-transactional MDBs - which in turn
force a redelivery. This behavior
is defined by the J2EE EJB specification.
For transactional MDBs I recommend instead calling
"setRollbackOnly()" on the EJB context.
You can use WL JMS' redelivery-limit and
error-destination features to control the number
of retries, and to redirect failed messages
to another destination.
Tom
Gurcan T. wrote:
> Here is the situation.
>
> 1. MDB is configured for a JMS Queue.
> 2. Inside the onMessage(), a call is made to business logic
> which invokes a series of Java classes.
> 3. Now there is a run time Exception somewhere deep in this
> business logic classes.
> 4. This exception is caught in onMessage().
> I would like to throw a new exception in order to escalate the error
> on the top level.
> 5. The container catches the runtime Exception and loop 3times in order to redeliver
> the
> message.
>
> Question: How to throw a new runtime exception on top level?
>
> I'm using WebLogic 7.0 SP2
>
> Any input on this problem is greatly appreciated.
> Thanks,
> Gurcan
>
-
JMS - How to configure incremental redelivery intervals for an MDB
Hi all,
I noticed that when message delivery in an MDB fails, the time to the next delivery attempt for the message increases with every failed delivery. The intervals are 5, 10, 20, 40 and 60 seconds. After this the interval stays at 60 seconds.
Now I was trying to find out how to change this behavior, but did not find the appropriate configuration elements in the console or the documentation. What I found are the options to configure "Default Redelivery Delay" in the ConnectionFactory which is set to 0 and in the Queue "Redelivery Delay Override" which is set to -1.
Both of these settings do not explain the incremental delay. Can anyone tell me how to configure this? Is that part of the MDB deployment descriptors?
Thanks,
ChrisHi Tom,
thanks again for your answer :-) I am sorry, i forgot to mention in my initial post, that i had a look at those parameters. But according to the documentation the default values for both are 60 seconds. In my MDB i did not set any of those, so it should not start at 5 seconds like it does but at 60 seconds. Additionally this suspension, I if understood correctly, should only kick in if the JMS resource (I figure this is the queue in this case) is unavailable, which is not the case in my scenario. And as a third the suspension described there is not growing exponentially as I experienced.
Sorry if I am just thick here, but the documentation just does not look like what I am looking for. Are there any misunderstandings on my side?
Thanks, Chris -
Redelivery of messages to JMS queue
Hi,
I am using weblogic 9.2 JMS and MDB for processing messages from queue. Only one instance of Container Managed MDB is running and the important point is that queue sequence should be maintained. I have a problem now. Each message will be picked by MDB and does some db lookups and it is sent over to another system. If there is any communication failure, the message has to be redelivered back to the front of the queue so that sequence is not lost. Even the same message is failing for more than one time, it should still be placed at the front of the queue becoz there is another mechanism that will pause the queue in case of communication exception.
I tried with throwing Runtime exception but it is crashing the MDB and is getting deployed again which I think is not the right approach.
I had set the transaction attribute as Required and tried to do setRollBackOnly on that for any exceptions but the message is not in the front of the queue. It is going to the back or somewhere in the queue.
I also tried to put the message back with higher priority but did not seem to work.
I have the redelivery delay as 0, I am not sure if I am missing any configuration settings. Pls let me know if there is a way to redeliver the message to the front of the queue for any exceptions in the message procesing by MDB.
Thanks
SriniSrini,
WebLogic JMS' Unit-of-Order (UOO) feature was very specifically designed to handle strictly ordered message processing. The feature ensures that messages with the same UOO name are processed strictly in order - regardless of the number of concurrent consumers, redelivery delays, rollbacks, etc.
If the entire queue is to be processed single threaded, you can very simply configure a default UOO for the queue, otherwise there are a variety of other UOO options. A good place to start is the JMS developer guide's UOO chapter.
And yes, "setRollbackOnly" is the best way to force a rollback of an MDB CMT.
Tom -
Configuring message redelivery with jmcjca (sun-jms-adapter) in Glassfish
I use Glassfish v2 server and its OpenMQ as JMS Provider.
My MDB is configured to use sun-jms-adapter for accessing JMS Provider.
ra.xml of adapter wasn't change so all configuration is done through the sun-ejb-jar.xml of my MDB.
Type of destination my MDB listens to is javax.jms.Topic.
At the same time, I have defined the following redelivery strategy in the sun-ejb-jar.xml
<activation-config-property>
<activation-config-property-name>RedeliveryHandling</activation-config-property-name>
<activation-config-property-value>2:1000; 3:move(queue:*psdmqqueue*)</activation-config-property-value>
</activation-config-property>
psdmqqueue is an administred server Destination of type javax.jms.Queue. So a target destination of MDB is topic and redelivery should be performed to queue
The problem is that application deplyment failes with this configuration with the following exception:
#|2008-11-22T18:38:48.152+0300|WARNING|sun-appserver9.1|com.stc.jmsjca.core.Activation|_ThreadID=169;_ThreadName=JMSJCA connect;_RequestID=ed86af75-1577-4548-ac57-60ca127a28a2;|JMSJCA-E016: [sync-Durable TopicSubscriber(provisioning_subscription)(lookup://targetTopic) @ [mq://localhost:7676/jms]]: message delivery initiation failed (attempt #85); will retry in 10 seconds. The error was: java.lang.ClassCastException: com.sun.messaging.jmq.jmsclient.XATopicSessionImpl
java.lang.ClassCastException: com.sun.messaging.jmq.jmsclient.XATopicSessionImpl
at com.stc.jmsjca.core.RAJMSObjectFactory.createDestination(RAJMSObjectFactory.java:423)
at com.stc.jmsjca.core.Delivery.createDLQDest(Delivery.java:626)
at com.stc.jmsjca.core.SyncDelivery.start(SyncDelivery.java:204)
at com.stc.jmsjca.core.Activation.asyncStart(Activation.java:535)
at com.stc.jmsjca.core.Activation.access$000(Activation.java:80)
at com.stc.jmsjca.core.Activation$1.run(Activation.java:343)
at java.lang.Thread.run(Thread.java:595)
Could you please help me to figure out what is wrong with my configuration?
Part of sun-ejb-jar.xml related to ra activation spec:
<mdb-resource-adapter>
<resource-adapter-mid>sun-jms-adapter</resource-adapter-mid>
<activation-config>
<activation-config-property>
<activation-config-property-name>ConnectionURL</activation-config-property-name>
<activation-config-property-value>lookup://targetConnFactory</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>Destination</activation-config-property-name>
<activation-config-property-value>lookup://targetTopic</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>DestinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Topic</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>RedeliveryHandling</activation-config-property-name>
<activation-config-property-value>2:1000; 3:move(queue:psdmqqueue)</activation-config-property-value>
</activation-config-property>
<!--subscription properties-->
</activation-config>
</mdb-resource-adapter>
</ejb>
</enterprise-beans>
</sun-ejb-jar>Hi Alexej,
I looked at the problem and found out what the issue is. We recently added some functionality that will test if the dead letter destination is in fact a valid destination -- we thought it's better to find that out upfront, rather than if an error occurs. This is especially important with dead letter destinations being looked up in JNDI: mistakes are easily be made there.
In any case, this new functionality introduced a problem where messages are sent from a queue, and the dead letter destination is a topic, or vice versa, where messages are received from a topic, and the dead letter destination is a queue.
In case you're wondering why: we still need to support JMS 1.0.2 servers. For these servers, the queues and topics are strictly segregated. We do have automated tests that test functionality across domains, but as it turns out, these tests also test some other functionality at the same time that fool the dead-letter-destination-validation into thinking it is the same messaging domain.
In any case, I've have created a fix for this, and I'm testing it right now.
I'll send you an updated RAR by email in case you don't want to wait until the updated bits are available for download. What you also could do, as a workaround, is doing the same trick that fooled the automated test: you can specify the redelivery handling in the MDB code, e.g.
public void onMessage(Message message) {
message.setStringProperty("JMS_Sun_JMSJCA_RedeliveryHandling", "2:1000; 3:move(queue:*psdmqqueue*)");
// do stuff
HTH, Frank Kieviet -
JMS (bea 9) redelivery does not work ?
I'm a bit at a loss. Any help is therefore welcome.
I am using Bea 9 and Java 1.5.
I have a MDB bean that attempts to transmit data to a foreign site via ftp. When it fails to transmit files, it errors and the message's content (a file) that I attempted to send to remote system is rollbacked. I have set the redelivery count to -1 and the redelivery delay to 1 minute. After a minute, the message is replayed and this as long as the bean is unable to transfer the file. This is what I wanted to do. And all is fine.
But...
If I stop the server while messages are waiting to be redelivered and then launch again the server just after, then the server only replays 2 or 3 messages (or 2 or 3 times the same message) and then stop replaying messages which should be redelivered every minute. New messages sent to the bean are also not presented to the bean. Everything seems frozen as far as this bean is concerned..
But, if I look at the console and display the monitoring info of this MDB after a restart, I read :
Beans In Use Count 0
Waiter Current Count 0
Timeout Total Count 0
Access Total Count 2
Destroyed Total Count 2
Connection Status Connected
Destination FtpQueue
JMS Client ID
Status running
Last Exception java.lang.Error: com.mycompany.FtpException: Could not connect to server ftpsrv2
It is "running"...
Any ideas ?
Thanks in advance for any tips.
P.Z.Hi,
Redelivery delays themselves are not persisted - messages that are subject to a redelivery delay should be immediately redelivered if their host JMS server is shutdown and restarted.
MDBs that are causing rollbacks/recovers have a built in pause/retry algorithm that causes them to automatically shutdown after a certain number of failures and then restart after an interval. The purpose is to prevent failing MDBs from running in a tight loop. The MDB edocs provide a bit more detail.
If this doesn't help, I have some questions that might help narrow down the problem:
-- Are the messages persistent?
-- Is the JMS server running on the same server as the MDB? If not, which server are you stopping?
-- How are you stopping the server?
-- What do the pending and current counts look like on the destination?
-- Are you using the "unit-of-order" feature?
Tom Barnes
WebLogic Messaging Developer Team -
JMS Clustering -- Automatic Redelivery
Hi:
Here is my understanding of distributed JMS. We are clustering three machines
(A, B and C).
Since JMS Servers themselves cannot have a cluster as a Target deployment,
We create a 3 JMS Servers
JMSServer1 with a Target of A
JMSServer2 with a Target of B
JMSServer3 with a Target of C
Now we create a distributed Queue/Topic. (JNDI Name - MyQueue)
We have the weblogic console autocreate topics and queues on each of the JMS
Servers. They are JNDI named something like MyQueue@JMSServer1 , MyQueue@JMSServer2
and MyQueue@JMSServer3
Now -- Correct me if I am wrong -- When I do a JNDI Lookup for MyQueue --
the WLConnectionfactory will give me a reference to an object in one of the three
servers right. Now after I get the reference, the server that I have a remote
reference goes down. When I try to post a message into the queue with the same
remote reference Is there any kind of automatic redelivery or a relookup and
get the next available server proxy (like in the EJB's) that is there ?
What happens in such a case? Can the JMS stub that I have on the client dynamically
(after it has been looked up) do redelivery on another server?
I understand that if I do a lookup again I will not be pinned to the machine
that just went down. This would be guaranteed by the ConnectionFactory right?
Please let me know if this is not the case.
Thanks and I really appreciate any help and input in the matter.
Vivek Bhaskaran
[email protected]
In our practice with Weblogic 7 JMS, we use distributed destination to handle sender
and MDB. If your sender fails because of JMS server down, you should catch exceptions
and resend it. When poll the message from the queue, we talk to the individual
physical queues directly.
"Vivek Bhaskaran" <[email protected]> wrote:
>
>Hi:
>
> Here is my understanding of distributed JMS. We are clustering three
>machines
>(A, B and C).
>
> Since JMS Servers themselves cannot have a cluster as a Target deployment,
>
> We create a 3 JMS Servers
> JMSServer1 with a Target of A
> JMSServer2 with a Target of B
> JMSServer3 with a Target of C
>
> Now we create a distributed Queue/Topic. (JNDI Name - MyQueue)
> We have the weblogic console autocreate topics and queues on each
>of the JMS
>Servers. They are JNDI named something like MyQueue@JMSServer1 , MyQueue@JMSServer2
>and MyQueue@JMSServer3
>
>
> Now -- Correct me if I am wrong -- When I do a JNDI Lookup for MyQueue
>--
>the WLConnectionfactory will give me a reference to an object in one
>of the three
>servers right. Now after I get the reference, the server that I have
>a remote
>reference goes down. When I try to post a message into the queue with
>the same
>remote reference Is there any kind of automatic redelivery or a relookup
>and
>get the next available server proxy (like in the EJB's) that is there
>?
>
> What happens in such a case? Can the JMS stub that I have on the
>client dynamically
>(after it has been looked up) do redelivery on another server?
>
> I understand that if I do a lookup again I will not be pinned to
>the machine
>that just went down. This would be guaranteed by the ConnectionFactory
>right?
>Please let me know if this is not the case.
>
> Thanks and I really appreciate any help and input in the matter.
>
>
>Vivek Bhaskaran
>[email protected]
-
JMS - rollback but no redelivery
All,
I have a simple pub/sub on weblogic 8.1 that has a independent thread doing sychronous consumption. The session is transacted. Everything is smooth except when I attempt to rollback a transaction. In such a case, the message is not redelivered when I re-invoke the receive method 1 minute later. It is discarded.
Looking at the pending messages on the queue, the message is always discarded 40 seconds after transaction is rolled back. If I shorten my wait and call the receive method 20 seconds after the rollback, the message is discarded after 20 seconds on the receive call. I was expecting to pull the message I had previously pulled.
Message has infinite lifespan, redelivery limit is infinite. I also created a template and hardcoded the redelivery limit for the jms server and topic with no success.
Any pointers or leads would be appreciated.
thanks - DanTom,
I pasted relevant pieces of config.xml and the listener code below, I hope it's intelligible. We're using the default ConnectionFactory.
We're using topics and TopicSubscriber for consumption. The flow here is consume a message through receive(), attempt to deliver this message to our client, rollback in case of failure, sleep 60 seconds, then attempt redelivery. When receive is invoked the second time, the message is gone. TopicSession code and the line that does invokes the rollback are surrounded by -------------.
- Dan
------------portions of config.xml---------------
(the first JmsServer entry was not created by me, second was)
<JMSServer Name="WSStoreForwardInternalJMSServerwlsD01S001"
Store="FileStore" Targets="wlsD01S001">
<JMSQueue CreationTime="1085198870801"
JNDIName="jms.internal.queue.WSStoreForwardQueue"
JNDINameReplicated="false" Name="WSInternaljms.internal.queue.WSStoreForwardQueuewlsD01S001"/>
<JMSQueue CreationTime="1085198871294"
JNDIName="jms.internal.queue.WSDupsEliminationHistoryQueue"
JNDINameReplicated="false" Name="WSInternaljms.internal.queue.WSDupsEliminationHistoryQueuewlsD01S001"/>
</JMSServer>
<JMSServer Name="Gov JMS Server WLSD04S001"
Store="Gov JMS File Store" Targets="wlsD01S001" TemporaryTemplate="MyJMS Template">
<JMSTopic CreationTime="1135118604257" JNDIName="GovJMSTopic"
Name="Gov JMS Topic" Template="MyJMS Template"/>
</JMSServer>
<JMSFileStore Directory="govJmsFileStore" Name="Gov JMS File Store"/>
<JMSTemplate ExpirationPolicy="Discard" Name="MyJMS Template" RedeliveryDelayOverride="0" RedeliveryLimit="250"/>
-----------------portions of listener code---------------
public class RubyMessageListener extends Thread
private TopicConnection topicConnection = null;
private TopicSession topicSession = null;
private TopicSubscriber topicSubscriber = null;
Context jndiContext = null;
private RubyMessageListener() {;}
public RubyMessageListener(String url, AgmemsFilter aFilter, ClientManager cmParam)
throws NamingException, JMSException, ConfigurationException
Create a JNDI API InitialContext object if none exists
yet.
jndiContext = new InitialContext();
We're taking care of the connection establishment at object
startup time so that if we throw exception, we can throw
exception back up to subscribe caller who can report NG to
client
Look up connection factory and queue. If either does
not exist, exit.
TopicConnectionFactory topicConnectionFactory = null;
Topic topic = null;
TextMessage message = null;
topicConnectionFactory = (TopicConnectionFactory) PortableRemoteObject.narrow(jndiContext.lookup("weblogic.jms.ConnectionFactory"), TopicConnectionFactory.class);
topic = (Topic) PortableRemoteObject.narrow(jndiContext.lookup("GovJMSTopic"), Topic.class);
Create connection.
Create session from connection; true means session is
transacted.
Create receiver, then start message delivery.
Close connection.
topicConnection = topicConnectionFactory.createTopicConnection();
topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
topicSubscriber = topicSession.createSubscriber(topic);
topicConnection.start();
myLogger.info("RubyMessageListener(): queue connection has been started, now listening on events");
public void confirmAndFallout(TopicSession ts, String sleepTime, boolean commitFlag)
try
if (commitFlag)
ts.commit();
myLogger.info("confirmAndFallout(): transaction is committed.");
else
ts.rollback();
myLogger.info("confirmAndFallout(): transaction successfully rolled back, must wait the sleepTime, " + sleepTime + " ms, before pulling message off of queue.");
try
Thread.sleep(Integer.parseInt(sleepTime));
catch (Exception e)
myLogger.error("confirmAndFallout(): After rollback, thread sleep failed, moving on without sleep.");
myLogger.info("confirmAndFallout(): sleep has been completed, return to event listening.");
return;
catch (JMSException je)
try
myLogger.error("confirmAndFallout(): Unable to confirm delivery transaction, sleep, then try once more before bailing.");
Thread.sleep(Integer.parseInt(sleepTime));
if (commitFlag)
ts.commit();
myLogger.info("confirmAndFallout(): transaction is committed.");
else
ts.rollback();
myLogger.info("confirmAndFallout(): transaction successfully rolled back.");
catch (Exception e)
myLogger.error("confirmAndFallout(): The second attempt at jms confirmation has failed, return.");
return;
public void run()
try
myLogger.info("run(): Client has asked us to begin pulling events for url: " + listenerUrl);
while (!haltFlag)
myLogger.info("run(): BACK up at top of receive loop");
StringBuffer errstr = new StringBuffer();
//receive will initiate our jms transaction,
//commit or rollback will end the transaction
//receive is blocking, wait 55 minutes before committing
//transaction and looping again. We do this to avoid
//default 60 minute transaction timeout
Message m = topicSubscriber.receive(3300000);
if (m != null)
if (m instanceof TextMessage)
TextMessage message = (TextMessage) m;
String messageText = "";
String eventType = "";
Document doc;
Node rootNode=null;
try
messageText = message.getText();
myLogger.info("run(): the following message has been pulled from the queue: " + messageText);
eventType = "";
doc = rubyxml.stringToXML(messageText);
rootNode = doc.getFirstChild();
catch (Exception e)
myLogger.error("run(): unable to understand the message we've pulled off the queue, commit transaction and continue. " + listenerUrl + " will not be receiving this message.");
confirmAndFallout(topicSession, listenerSleep, true);
continue;
String operationNodeName = "";
if (rootNode!=null)
operationNodeName = rootNode.getNodeName();
myLogger.info("run(): operationNodeName: " + operationNodeName);
if (operationNodeName.equals("tktInfoEvt"))
eventType = "tktInfoEvt";
else if (operationNodeName.equals("prmInfoEvt"))
eventType = "prmInfoEvt";
else if (operationNodeName.equals("rubyFacilityStatusEvt"))
eventType = "rubyFacilityStatusEvt";
else if (operationNodeName.equals("killEvt"))
eventType = "killEvt";
else
eventType = "heartbeatEvt";
/** If the message is a rubyFacilityStatusEvt,
tktInfoEvt, or prmInfoEvt
- perform filter(listenerUrl, mcn) to determine
whether our client cares about this message
- if client cares, stamp(url) to refresh clock,
convert the xml string to java class, and send
message
- if client does not care, invoke discardedMsg(mcn)
and commit the transaction
- if ws request succeeds, commit
- if ws request fails, rollback and sit tight
for one minute
else if (eventType.equals("rubyFacilityStatusEvt") ||
eventType.equals("tktInfoEvt") ||
eventType.equals("prmInfoEvt"))
String mcn = rubyxml.getValueByTag((Element)rootNode, "mcn", errstr);
if (gs.filter(listenerUrl, mcn)
== AgmemsFilter.FILTER_PASSED)
myLogger.info("run(): we've pulled a " + eventType + " message off of the queue and it's time to send it out to client: " + listenerUrl);
messageCount += 1;
Socket agmemsSocket = null;
try
if (eventType.equals("rubyFacilityStatusEvt"))
agmemsSocket = HttpUtilities.sendCommand(cu.populateFacilityEvt(facStatusServiceUrl, messageText, messageCount, facStatusAction, rdate, agmemsUsername, agmemsPassword, "", false), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), facStatusServiceUrl);
else if (eventType.equals("tktInfoEvt"))
agmemsSocket = HttpUtilities.sendCommand(cu.populateTicketEvt(tktInfoServiceUrl, messageText, messageCount, tktInfoAction, rdate, agmemsUsername, agmemsPassword), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), tktInfoServiceUrl);
else
agmemsSocket = HttpUtilities.sendCommand(cu.populatePrmEvt(prmInfoServiceUrl, messageText, messageCount, prmInfoAction, rdate, agmemsUsername, agmemsPassword), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), prmInfoServiceUrl);
catch (Exception e)
//these are the kind of failures,
//timeout, socketException, etc. that we
//would like to retry
myLogger.error("run(): ERROR, " + eventType + " push was unable to be sent to " + listenerUrl + " because of following exception, rolling back transaction." + e);
------------------------ confirmAndFallout(topicSession, listenerSleep, false);
continue;
myLogger.info("run(): Continued to readReplyFromSocket");
StringBuffer respStr = new StringBuffer();
try
HttpUtilities.readReplyFromSocket
(agmemsSocket, respStr);
myLogger.info("run(): response returned was " + respStr);
catch (Exception ie)
//rollback, something wrong on client side
myLogger.error("run(): ERROR, " + eventType + " NOT delivered to " + listenerUrl + " rolling back transaction. " + ie.toString());
confirmAndFallout(topicSession, listenerSleep, false);
continue;
int agmemsMessageNumber=0;
agmemsMessageNumber =
cu.parseAgmemsResponse(respStr.toString());
if ((agmemsMessageNumber==-1) ||
(agmemsMessageNumber!=messageCount))
confirmAndFallout(topicSession, listenerSleep, true);
myLogger.error("run(): ERROR, " + eventType + " push response came back with NOT delivered to " + listenerUrl + " confirming transaction.");
else
confirmAndFallout(topicSession, listenerSleep, true);
myLogger.info("run(): " + eventType + " delivered to " + listenerUrl + " and transaction is committed.");
//Assumes CLIENT_INACTIVE return
else
//commit for cleanup only
confirmAndFallout(topicSession, listenerSleep, true);
setHaltFlag(true);
myLogger.error("run(): " + eventType + " NOT delivered to " + listenerUrl + ", CLIENT_INACTIVE, halting message receive on this listener.");
else
myLogger.error("run(): we've pulled a text message from the queue that is UNKNOWN, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
else
myLogger.error("run(): we've pulled a message from the queue that is UNKNOWN and not text, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
else
myLogger.error("run(): something strange happened, receive() returned with NO MESSAGE, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
catch (JMSException je)
myLogger.error("run(): ERROR, exception, cleanup connections: " + je.toString());
catch (Exception e)
myLogger.error("run(): ERROR, exception, cleanup connections: " + e.toString());
finally
myLogger.error("run(): broken out of message receive loop, closing session, subscription, and topicConnection and KILLING this thread.");
if (topicConnection != null)
try
cm.listenerTable.remove(listenerUrl);
topicSession.close();
topicSubscriber.close();
topicConnection.close();
catch (JMSException e)
myLogger.error("run(): As part of cleanup process, there was an exception attempting to close our topicConnection.");
Message was edited by:
whoopsy -
I have a MDB (Bean managed Transaction) listening to a MQ.
App server used: weblogic 8.1
While a message is being processed in the onMessage() of this MDB and if server goes down, will the message be redelivered the next time I start the server?
At what point is the message removed from MQ?
Thanks
MKPHi,
quote from edocs:
"if an application fails, a transaction rolls back, or the hosting server instance fail during or after the onMessage() method completes but before the message is acknowledged or committed, the message will be redelivered and processed again. "
So if you are not acknowledging it before onMessage is completed, it should be reprocessed (Depending also on the redelivery settings of the JMS Queue)
-Kai -
I have two simple questions:
1. Let's suppose a situation when a table lock is present in our database and the MDB regularly runs into this lock every time when the onMessage method is called. It always reserves a new MDB because the MDB created by the previous call is not capable to move back to the pool becaus of the lock. It means if there is no more free bean in the pool a new bean will be created. Hence a simple database lock can cause application server to run out of system resources.
Is there any way to catch the timeout or how can I avoid this situation?
2. If consumption of the message fails the message is redelivered successively but the reason of the failure is still present. I wouldn't like to lose these failed messages. Do I have to move these to another queue or is there any standard scenario for this kind of situation? Can I delay the redelivery?
Thanks in advanceTo the second question, it is dependant of your JMS providers. It may include these configuration parameters to fine-tune redelivery:
* Redelivery count: The number of times to redeliver a message. Redelivery count is important because poison messages, messages the application can never successfully process, can eventually crash the system.
* Exception destination: What happens to a message that is redelivered redelivery-count times? The JMS provider can do any of the following:
o Log the message
o Forward the message to an exception or error destination
o Lose the message
* Time to redeliver: An application that has just rolled back messages might not be ready to reprocess the same messages. This parameter specifies the time to wait before redelivering the message. This delay lets the JMS provider and the application recover to a stable state.
I know that in weblogic, you can specify this parameters when you specify your JMS settings.
Actually I work with BES 5.2.1, and I can not specify this settings. It will be a new feature of BES 6. -
Message redelivery with non-transactional message bean JMS standard or weblogic standard?
It is my understanding (or maybe my assumption) that a message is
re-queued only if the transaction attribute of a container-managed
message bean is set to "Required" and the message is PERSISTENT. So if
it's set to "NotSupported", and thus, message receival is not within a
transaction, the message would be un-queued and thus never be
redelivered, should a failure occur within the bean. I discovered that
even if the message bean is set as "NotSupported", should a failure
occur within the bean, the message is re-queued to be received again
at a later time.
I'm very confused as to whether this mechanism is a JMS standard, or a
feature of Weblogic. Well, maybe I'm just confused about message
delivery/re-delivery. I understand that the JMS standard requires
guaranteed delivery of a message to a receiver. Does this mean a
message is only considered delivered if an acknowledgement is
received, regardless of the transaction level? In other words, is the
JMS standard that a message is considered delivered only if
acknowledgement is indicated through the container, regardless of the
transaction level of the message bean itself?
You're right on the second part. That is, a JMS message is not considered to
be "delivered" until it is acknowledged. There are a number of ways to make
this happen when programming to the raw JMS API -- a look at the Javadoc for
JMS or a good JMS book should clarify how to do this.
With a message-driven bean, the EJB container acknowledges the message after
you've successfully returned from the "onMessage" method. If you throw a
RuntimeException from the "onMessage" method, or if it's an MDB with a
transaction mode of "Required" and you call "setRollbackOnly" on the
"MessageDrivenContext" object -- then your message will be redelivered.
Regardless of how a message is acknowledged, if it's not acknowledged then
it will be redelivered. This has nothing to do with whether the message is
persistent. The difference is that if a message is persistent, then the JMS
server is required to keep a copy on stable storage until the message is
acknowledged so that if the JMS server itself crashes, the message will not
be lost. For a non-persistent message, on the other hand, if the JMS server
crashes, then the message may be lost.
greg
"Justin" <[email protected]> wrote in message
news:[email protected]...
> It is my understanding (or maybe my assumption) that a message is
> re-queued only if the transaction attribute of a container-managed
> message bean is set to "Required" and the message is PERSISTENT. So if
> it's set to "NotSupported", and thus, message receival is not within a
> transaction, the message would be un-queued and thus never be
> redelivered, should a failure occur within the bean. I discovered that
> even if the message bean is set as "NotSupported", should a failure
> occur within the bean, the message is re-queued to be received again
> at a later time.
>
> I'm very confused as to whether this mechanism is a JMS standard, or a
> feature of Weblogic. Well, maybe I'm just confused about message
> delivery/re-delivery. I understand that the JMS standard requires
> guaranteed delivery of a message to a receiver. Does this mean a
> message is only considered delivered if an acknowledgement is
> received, regardless of the transaction level? In other words, is the
> JMS standard that a message is considered delivered only if
> acknowledgement is indicated through the container, regardless of the
> transaction level of the message bean itself?
-
JMS message redelivery in EJB 3
Hi,
We are using EJB 3, message driven bean as a subscriber to JMS queues.
I am looking for an option which could enable us in driving the redeliver on failure & forwarding the messages to different queue in case of failure & reprocessing of messages on failure.
Does anybody has any idea how can we do this.
Can it we done through annotations or there is some other way.
Thanks & Regards,
Manish
Edited by: mjain1983 on May 31, 2009 9:27 PMManish,
These options will be provided by most of the application servers and can be easily configured.
What is the application server that you are using? -
Using OC4J 9.0.4.0.0 i've set up a message driven ejb that consumes messages from a queue. I've got a scenario whereby on rare occasions my bean won't be able to process the message due to the absence of an external service. When this happens, i roll back the transaction so the message is returned to the queue, the idea being that it can be processed later when the external service may/may not be available.
The problem is that the message is redelivered straight away - i want to be able to specify a delay. Can anyone help?Try the following two attributes.
dequeue-retry-count="10"
dequeue-retry-interval="300".
For me it didn't help.I have my Oracle Advanced Queue's as my JMS Provider.So I changed init parameters for my Oracle where I have queues , as follows.
ALTER SYSTEM SET aq_tm_processes=1;
It then started working as expected.
Good luck.
Giri Kosuru.
Sample orion-ejb-jar.xml
<message-driven-deployment
name="GiriMDB"
connection-factory-location= "java:comp/resource/prototypeRP/TopicConnectionFactories/myTCF"
destination-location="java:comp/resource/prototypeRP/Topics/rpTestTopic"
subscription-name="MDBSUB"
dequeue-retry-count="10"
dequeue-retry-interval="300"
listener-threads="1"> -
JMS Message redelivery in BPEL
Hi,
I have a requirement that I want to distinguish the instance consuming original message from the instance consuming the retried message.
eg. I have the requirement that if its the original message then I need to take the action A in the BPEL and if it is the retried one then I want to take the action B.
Is there some mechanism with which I can differentiate the above stuff?
Thanks in Advance.
Best Regards,
Amit JainHi,
I have got the solution to above issue.
Once my JMS adapter picks the message, it passed the message to BPEL through mediator.
In Mediator assign, by using $in.property.jca.jms.JMSProperty.JMSXDeliveryCount I got the value.
Thanks & Regards,
Amit Jain
Maybe you are looking for
-
OSX Lion Server / Mail.app with FB
Hi - I have an OSX mac mini i7 Lion Server 10.7.4 running mail server. I am getting emails from gmails but apparently, it is not getting email from Facebook registration. I tried many times but no facebook registration comes in. I tried sending email
-
Airport Extreme Disk works great on OSX and Windows XP but no go on Vista
Just bought the Airport Extreme and attached a Seagate 320GB HDD to the USB port (formatted MAC journaled). Using the Airport Disk Ultility, I can access the NAS drive and read/write files from a 24" iMac and Windows XP PC. But on the Vista PC, Airpo
-
Higher Education cess not displayed in J2I6 when posted through J1IH
Hi, We have passed an Excise JV through J1IH. BED, ECess and HECess accounts are credited and Excise Duty paid A/c is debited. All the values are posted properly. We have also checked the accounting document for this. But when we run the report J2I6
-
Analyzer has encountered a problem error
some of our PC's are suddenly reporting an error stating - "analyzer has encountered a prblem and needs to close we are sorry for the inconvenience." The event logs have several zen errors most coming from sources listed as Novell.Zenworks.Logger, Ap
-
Z10 camera not focusing,not ringing at times and randomly calling out
I'm having issues with my camera not focusing, just started yesterday, also at times incoming calls will not ring and go directly to voice mail, and randomly calling someone with out showing it called