ActiveMQ Session AUTO_ACKNOWLEDGE property impact - session

Can anyone please explain me what is the impact of Session.AUTO_ACKNOWLEDGE for ActiveMQ JMS configurations
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

I believe by default ActiveMQ is set to auto acknowledge messages. This just means that when a message arrives it will automatically acknowledge that the message arrived. It is the same thing as calling .acknowledge() from the JMS object.
One reason to turn auto-acknowledge off is if you built a server and lets say you are processing each JMS Message and are doing some sort of DB transaction. If the transaction fails you would want the JMS message to be re-sent so you can fix your error and process it again. So in this sense you would only acknowledge the JMS object only after processing.

Related

JMS Session Pooling with Message Listener

Relating to this question (JMS Connection Pooling in Message Listener), i'm currently trying to build a session pool upon a pool of connections that i'd created earlier.
I had managed to create a pool of JMS Connections and when i run it with my Producers and Consumers, they work fine. The Consumers is registered with a Message Listener to retrieve messages from the MQ.
However when i implemented the session pool, the message listener just stop working. The producers can send message out without problem, but the message listener never fired off.
The following code is the create code in the JmsSessionObjectFactory:
Connection connection = Application.getInstance().getConnectionPool().borrowObject();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
Application.getInstance().getConnectionPool().returnObject(connection);
Is that the correct way to implement the factory creation for a session? Or my concept of session pooling with the connection pool is wrong?
Appreciate any advice. Thank you.

single jms consumer for multiple jms servers

I am using a distributed jms queue and weblogic is my app server. There are three jms servers deployed in my clustered enviroment. The producers just send the message using name of queue jndi lookup 'udq' for example. Now I have associated a consumer for each jms server and I was able to consume the message, no problem so far.
Here is question, can I have a single consumer to consume the messages from the 3 jms servers. The weblogic allows jndi naming for destination lookup with following syntax #
qsession1 = qcon1.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
qsession2 = qcon2.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
qsession3 = qcon3.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue1 = (Queue)ctx.lookup("JMSServer-1#UDQ");
queue2 = (Queue)ctx.lookup("JMSServer-2#UDQ");
queue3 = (Queue)ctx.lookup("JMSServer-3#UDQ");
qreceiver1 = qsession1.createReceiver(queue1);
qreceiver2 = qsession2.createReceiver(queue2);
qreceiver3 = qsession3.createReceiver(queue3);
qreceiver1.setMessageListener(this);
qreceiver2.setMessageListener(this);
qreceiver3.setMessageListener(this);
qcon1.start();
qcon2.start();
qcon3.start();
I have only one OnMessage implemented for the above consumer. This does not work. Any suggestions please..
No, you can't have a consumer receiving messages from more than one JMS server. A consumer can receive messages from only one JMS server. You need to create multiple consumers to receive messages from multiple JMS servers.
you can use "Queue Forwarding" function.
From online documentation of wls 10.3:
"Queue members can forward messages to other queue members by configuring the Forward Delay attribute in the Administration Console, which is disabled by default. This attribute defines the amount of time, in seconds, that a distributed queue member with messages, but which has no consumers, will wait before forwarding its messages to other queue members that do have consumers."
here a link: http://docs.oracle.com/cd/E13222_01/wls/docs103/jms/dds.html#wp1260816
You can configure this feature from administration of each single queue.

How do I hold a jms message in queue until it is saved?

I just started using Weblogic JMS. I was able to send messages to the queue and pull them off with a messagebean. Now I want to save the message to a database.
So my question is, how do I tell JMS not to delete the message from the queue until I have successfully written the message to the database?
Thanks
I was able to send messages to the queue and pull them off with a
messagebean.
I suppose you are talking about message-driven bean (MDB)?
So my question is, how do I tell JMS not to delete the message from
the queue until I have successfully written the message to the
database?
MDBs are part of implicit container-managed transaction and the message will not be removed as long as your transaction hasn't commited (that is, as long as your onMessage method hasn't reached its end).
In case of rollback (i.e. you throw an exception or call context.setRollbackOnly() on the MessageDrivenContext), message will be redelivered. You can avoid this behaviour by making transaction bean-managed or using #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED), but in your situation that should not be the case. Stick with default configuration and everything should work as you wish.

JMS Message wasn't deleted after it was received

What can be the reason of this problem?
Connection, Session were closed at the end.
I use WebLogic as JMS Broker. And I didn't find autodelete after receive option in JMS Queue configuration.

about Session.rollBack() in JMS

All,
i am new to JMS and i have a question about Session.rollBack() method in JMS. AFAIK, this method is used to roll back all operations to JMS server (sending/receiving) by the session when using *SESSION_TRANSACTED* acknowledge mode. Now suppose I am calling this method in a catch block of a receiving/processing operation (is reasonable?), to tell JMS server to redeliver the message for processing, But even if it is redelivered the processing still throws the same exception which cause the JMS server to redeliver the message again, so it seems a infinite process. How to handle this problem? or are there any other JMS features that is designed for it? Thanks in advance!
The rollback method in JMS will rollback any message sends and receives in that "transaction". Transaction here is local to the JMS session.
Whether a redelivery will cause a problem really depends on why the exception occurred. If it was due to some transitory issue then a redelivery may work. If you have the kind of problem that is once it occurs will always occur (an example of this would be a JMS TextMessage whose body should contain XML, but doesn't).
The JMS API doesn't provide any solution to this itself. This is typically taken care of by the JMS provider and how it behaves will depend on which one you use. WebSphere MQ for instance will redeliver up to a configurable maximum at which point it will move it off to a queue for bad messages. The Service Integration Bus in WebSphere Application Server has similar behaviour. I suggest you consult your JMS provider documentation to determine exactly how it behaves in this situation.
If you are running in an application server rollback typically doesn't do anything because the application server will be managing transactions for you.

Resources