Sun Java System Message Queue 3 2005Q1 Developer's Guide for Java Clients |
Chapter 4
Program FeaturesThis chapter describes custom client acknowledgment, which is a Message Queue extensions to the JMS API. It covers the following topics:
For a discussion of issues related to Message Queue program architecture and configuration, see Chapter 3.
IntroductionMessage Queue supports the standard JMS acknowledgement modes (AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, and DUPS_OK_ACKNOWLEDGE). When you create a session for a consumer, you can specify one of these modes. Your choice will affect whether acknowledgement is done explicitly (by the client application) or implicitly (by the session) and will also affect performance and reliability. This section describes additional options you can use to customize acknowledgment behavior:
The following sections explain how you program these options.
Using Client Acknowledge ModeFor more flexibility, Message Queue lets you customize the JMS CLIENT_ACKNOWLEDGE mode. In CLIENT_ACKNOWLEDGE mode, the client explicitly acknowledges message consumption by invoking the acknowledge() method of a message object. The standard behavior of this method is to cause the session to acknowledge all messages that have been consumed by any consumer in the session since the last time the method was invoked. (That is, the session acknowledges the current message and all previously unacknowledged messages, regardless of who consumed them.)
In addition to the standard behavior specified by JMS, Message Queue lets you use the CLIENT_ACKNOWLEDGE mode to acknowledge one message at a time.
Observe the following rules when implementing custom client acknowledgement:
- To acknowledge an individual message, call the acknowledgeThisMessage() method. To acknowledge all messages consumed so far, call the acknowledgeUpThroughThisMessage() method. Both are shown in Code Example 4-1.
- When you compile the resulting code, include both imq.jar and jms.jar in the classpath.
- Don’t call acknowledge(), acknowledgeThisMessage(), or acknowledgeUpThroughThisMessage() in any session except one that uses the CLIENT_ACKNOWLEDGE mode. Otherwise, the method call is ignored.
- Don’t use custom-acknowledgement in transacted sessions. A transacted session defines a specific way to have messages acknowledged.
If a broker fails, any message that was not acknowledged successfully (that is, any message whose acknowledgement ended in a JMSException) is held by the broker for delivery to subsequent clients.
Code Example 4-2 demonstrates both types of custom client acknowledgement.
Code Example 4-2 Example of Custom Client Acknowledgement Code
...
import javax.jms.*;
... [Look up a connection factory and create a connection.]
Session session = connection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);
... [Create a consumer and receive messages.]
Message message1 = consumer.receive();
Message message2 = consumer.receive();
Message message3 = consumer.receive();
... [Process messages.]
... [Acknowledge one individual message.
Notice that the following acknowledges only message 2.]
((com.sun.messaging.jms.Message)message2).acknowledgeThisMessage();
... [Continue. Receive and process more messages.]
Message message4 = consumer.receive();
Message message5 = consumer.receive();
Message message6 = consumer.receive();
... [Acknowledge all messages up through message 4. Notice that this
acknowledges messages 1, 3, and 4, because message 2 was acknowledged
earlier.]
((com.sun.messaging.jms.Message)message4).
acknowledgeUpThroughThisMessage();
... [Continue. Finally, acknowledge all messages consumed in the session.
Notice that this acknowledges all remaining consumed messages, that is,
messages 5 and 6, because this is the standard behavior of the JMS API.]
message5.acknowledge();
Using No Acknowledge ModeThe NO_ACKNOWLEDGE acknowledgement mode is a non-standard extension to the Java Messaging Specification API(JMS). Normally, the broker waits for a client acknowledgement before considering that a message has been acknowledged and discarding it. That acknowledgement must be made programmatically if the client has specified CLIENT_ACKNOWLEDGE or it can be made automatically, by the session, if the client has specified AUTO_ACKNOWLEDGE or DUPS_OK. If a consuming client specifies the NO_ACKNOWLEDGE mode, the broker discards the message as soon as it has sent it to the consuming client. This feature is intended for use by non-durable subscribers consuming non-persistent messages, but it can be used by any consumer.
Using this feature improves performance by reducing protocol traffic and broker work involved in acknowledging a message. This feature can also improve performance for brokers dealing with misbehaving clients who do not acknowledge messages and therefore tie down broker memory resources unnecessarily. Using this mode has no effect on producers.
You use this feature by specifying NO_ACKNOWLEDGE for the acknowledgeMode parameter to the createSession, createQueueSession, or createTopicSession method. The NO_ACKNOWLEDGE mode must be used only with the connection methods defined in the com.sun.messaging.jms package. Note however that the connection itself must be created using the javax.jms package.
The following are sample variable declarations for connection, queueConnection and topicConnection:
javax.jms.connection Connection;
javax.jms.queueConnection queueConnection
javax.jms.topicConnection topicConnection
The following are sample statements to create different kinds of NO_ACKNOWLEDGE sessions:
//to create a no ack session
Session noAckSession =
((com.sun.messaging.jms.Connection)connection)
.createSession(com.sun.messaging.jms.Session.NO_ACKNOWLEDGE);// to create a no ack topic session
TopicSession noAckTopicSession =
((com.sun.messaging.jms.TopicConnection) topicConnection)
.createTopicSession(com.sun.messaging.jms.Session.NO_ACKNOWLEDGE);//to create a no ack queue session
QueueSession noAckQueueSession =
((com.sun.messaging.jms.QueueConnection) queueConnection)
.createQueueSession(com.sun.messaging.jms.Session.NO_ACKNOWLEDGE);Specifying NO_ACKNOWLEDGE for a session results in the following behaviors:
- The client runtime will throw a JMSException if Session.recover() is called on a NO_ACKNOWLEDGE session.
- The client runtime will ignore a call to the Message.acknowledge() method from a consumer belonging to a session with NO_ACKNOWLEDGE mode set.
- Messages can be lost. As opposed to the DUPS_OK mode, which can result in duplicate messages being sent, this mode bypasses checks and balances built into the system and may result in message loss.