activemq-artemis/examples/jms/pre-acknowledge
Martyn Taylor 73c5f2e342 [maven-release-plugin] prepare for next development iteration 2015-05-13 15:24:55 +01:00
..
src/main Ensure all references to the project use ActiveMQ Artemis 2015-05-13 11:51:26 +01:00
pom.xml [maven-release-plugin] prepare for next development iteration 2015-05-13 15:24:55 +01:00
readme.html Ensure all references to the project use ActiveMQ Artemis 2015-05-13 11:51:26 +01:00

readme.html

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<html>
  <head>
    <title>ActiveMQ Artemis JMS Pre-Acknowledge Example</title>
    <link rel="stylesheet" type="text/css" href="../common/common.css" />
    <link rel="stylesheet" type="text/css" href="../common/prettify.css" />
    <script type="text/javascript" src="../common/prettify.js"></script>
  </head>
  <body onload="prettyPrint()">
     <h1>JMS Pre-Acknowledge Example</h1>

     <p>Standard JMS supports three acknowledgement modes: AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, and
     DUPS_OK_ACKNOWLEDGE. For a full description on these modes please consult the JMS specification, or any
     JMS tutorial.</p>
     <p>All of these standard modes involve sending acknowledgements from the client to the server. However
     in some cases, you really don't mind losing messages in event of failure, so it would make sense
     to acknowledge the message on the server <b>before</b> delivering it to the client.</p>
     <p>By acknowledging the message before sending to the client, you can avoid extra network traffic and CPU
     work done in sending acknowledgements from client to server.</p>
     <p>The down-side of acknowledging on the server before delivery, is that if the system crashes after acknowledging
     the message, but before the message has been received by the client, then, on recovery, that message
     will be lost. This makes pre-acknowledgement not appropriate for all use cases, but it is very useful for some
     use-cases when you can cope with such loss of messages<p>
     <p>An example of a use-case where it might be a good idea to use pre-acknowledge, is for stock price update
     messages. With these messages it might be ok to lose a message in event of crash, since the next price
     update message will arrive soon, overriding the previous price.</p>
     <p>In order to use pre-acknowledge functionality with ActiveMQ Artemis the session has to be created with
     a special, ActiveMQ Artemis specific acknowledgement mode, given by the value of
     <code>ActiveMQJMSConstants.PRE_ACKNOWLEDGE</code>.     
     <h2>Example step-by-step</h2>
     <p><i>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</i></p>

     <ol>
        <li>Create an initial context to perform the JNDI lookup.</li>
        <pre class="prettyprint">
           <code>
     initialContext = getContext(0);
     </code>
        </pre>

        <li>Perform the look-ups</li>
        <pre class="prettyprint">
           <code>
     Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");

     ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");                      
           </code>
        </pre>

        <li>Create a the JMS objects.</li>
        <pre class="prettyprint">
           <code>
     connection = cf.createConnection();

     Session session = connection.createSession(false, ActiveMQSession.PRE_ACKNOWLEDGE);

     MessageProducer producer = session.createProducer(queue);
         
     MessageConsumer messageConsumer = session.createConsumer(queue);           
           </code>
        </pre>

        <li>Create and send a message.</li>
        <pre class="prettyprint">
           <code>
     TextMessage message1 = session.createTextMessage("This is a text message 1");

     producer.send(message1);

     System.out.println("Sent message: " + message1.getText());           
           </code>
        </pre>

        <li>Print out the message count of the queue. The queue contains one message as expected
        delivery has not yet started on the queue.</li>
        <pre class="prettyprint">
           <code>
     int count = getMessageCount(connection);
       
     System.out.println("Queue message count is " + count);           
           </code>
        </pre>

        <li>Start the Connection, delivery will now start. Give a little time for delivery to occur.</li>
        <pre class="prettyprint">
          <code>
     connection.start();

     Thread.sleep(1000);          
          </code>
       </pre>

        <li>Print out the message count of the queue. It should now be zero, since the message has
         already been acknowledged even before the consumer has received it.</li>         
        <pre class="prettyprint">
           <code>
     count = getMessageCount(connection);         
     
     System.out.println("Queue message count is now " + count);
           </code>
        </pre>

        <li>Finally, receive the message.</li>
        <pre class="prettyprint">
           <code>
     TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);

     System.out.println("Received message: " + messageReceived.getText());           
           </code>
        </pre>

        <li>Be sure to close our resources!</li>
          <pre class="prettyprint">
           <code>
     if (initialContext != null)
     {
        initialContext.close();
     }
     if (connection != null)
     {
        connection.close();
     }           
           </code>
        </pre>
     </ol>
     
     <h2>More information</h2>
     
     <ul>
         <li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#pre-acknowledge">Pre-acknowledgement Mode chapter</a></li>
     </ul>
     
  </body>
</html>