ActiveMQ
  1. ActiveMQ
  2. AMQ-2577

Acknowleging a single message actually acknowleges all messages consumed.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Not a Problem
    • Affects Version/s: 5.3.0
    • Fix Version/s: 5.3.0
    • Component/s: JMS client
    • Labels:
      None
    • Environment:

      Mac OSX 10.6, CentOS 5 Linux

      Description

      If I publish a bunch of messages, and then consume them with a session Session.CLIENT_ACKNOWLEDGE, when I acknowlege the first messages, all messages actually get acknowledged. I'm including some source code that shows the problem.

      This problem can be seen regardless of the Session be transacted or not.

      Thanks,
      Brad

      package bugs;

      import javax.jms.*;
      import java.util.LinkedList;
      import java.net.*;
      import org.apache.activemq.*;

      /**
      *

      • @author bwillard
        */
        public class MessageAcknowledgementBug {

      public static void main(String[] args) {

      try {

      ConnectionFactory factory = new ActiveMQConnectionFactory(URI.create("tcp://localhost:61616"));

      Connection jmsConn = factory.createConnection();
      jmsConn.start();

      Session session = jmsConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);

      Queue queue = session.createQueue("Ack.Bug.Test");

      MessageProducer publisher = session.createProducer(queue);
      TextMessage msg;

      /*

      • Put 50 Messages on Queue
        */
        for (int a = 0; a < 50; a++) { msg = session.createTextMessage("" + a); publisher.send(msg); }

      MessageConsumer reader = session.createConsumer(queue);

      LinkedList<TextMessage> messages = new LinkedList<TextMessage>();

      /*

      • Receive all 50 messages and store in list
        */

      while ((msg = (TextMessage) reader.receiveNoWait()) != null)

      { messages.add(msg); }

      /*

      • acknowledge one message, which acknowledges them all as received
      • instead of just the one message
        */

      messages.getFirst().acknowledge();

      reader.close();
      publisher.close();

      jmsConn.stop();
      jmsConn.close();

      } catch (Exception exc)

      { exc.printStackTrace(); }

      }
      }

        Activity

        Hide
        Brad Willard added a comment -

        This behavior is defined in the JMS Specification. I think this is really a flaw in the design of the specification. ActiveMQ supports the spec properly, it's the spec that's misleading.

        Show
        Brad Willard added a comment - This behavior is defined in the JMS Specification. I think this is really a flaw in the design of the specification. ActiveMQ supports the spec properly, it's the spec that's misleading.
        Hide
        Brad Willard added a comment -

        Wow is that a misleading flaw in the JMS Spec, I guess I'll go write them about that. Thanks for the info on INDIVIDUAL_ACKNOWLEDGE. I just started using that and it works like a charm.

        Thanks,
        Brad

        Show
        Brad Willard added a comment - Wow is that a misleading flaw in the JMS Spec, I guess I'll go write them about that. Thanks for the info on INDIVIDUAL_ACKNOWLEDGE. I just started using that and it works like a charm. Thanks, Brad
        Hide
        Timothy Bish added a comment -

        This is actually exactly how CLIENT_ACKNOWLEDGE works.

        From the JMS Specification:

        With this acknowledgment mode, the client acknowledges a consumed message by calling the message's acknowledge method. Acknowledging a consumed message acknowledges all messages that the session has consumed.

        ActiveMQ has a special acknowledge mode called INDIVIDUAL_ACKNOWLEDGE that can be used if you really want to ack only a single message at a time.

        Show
        Timothy Bish added a comment - This is actually exactly how CLIENT_ACKNOWLEDGE works. From the JMS Specification: With this acknowledgment mode, the client acknowledges a consumed message by calling the message's acknowledge method. Acknowledging a consumed message acknowledges all messages that the session has consumed. ActiveMQ has a special acknowledge mode called INDIVIDUAL_ACKNOWLEDGE that can be used if you really want to ack only a single message at a time.

          People

          • Assignee:
            Unassigned
            Reporter:
            Brad Willard
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development