Uploaded image for project: 'ActiveMQ'
  1. ActiveMQ
  2. AMQ-6697

Aborting a STOMP 1.1 transaction after ACK/NACK leads to invalid state

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.14.5
    • Fix Version/s: 5.15.0, 5.14.6
    • Component/s: STOMP
    • Labels:
      None

      Description

      Reproducing the problem:

      • Receive a message via STOMP (EDIT: on a subscription with ack:client-individual)
      • Start a transaction
      • ACK (or NACK) the message within the transaction
      • Abort the transaction
      • ACK (or NACK) the message

      Expected behaviour:

      • The message is according to step #5 either ACKed or NACKed.

      Observed behaviour:

      • The message is neither ACKed nor NACKed, but stays in unacknowledged state
      • An exception is raised:
        org.apache.activemq.transport.stomp.ProtocolException: Unexpected ACK received for message-id [ID:(...)]
        at org.apache.activemq.transport.stomp.ProtocolConverter.onStompAck(ProtocolConverter.java:475)
        at org.apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:250)
        at org.apache.activemq.transport.stomp.StompTransportFilter.onCommand(StompTransportFilter.java:85)
        at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
        at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
        at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
        at java.lang.Thread.run(Thread.java:745)
      • an ERROR message is sent to the client

      As far as I can tell this is caused by code in both onStompAck() and onStompNack():
      https://git-wip-us.apache.org/repos/asf?p=activemq.git;a=blob;f=activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/ProtocolConverter.java;h=b25860bf6895240c33a8643b6fcc731af126d32e;hb=refs/heads/master#l440

      With a STOMP 1.1 ACK/NACK, ackId == null, so the message entry is taken out of this.pedingAcks (sic!).
      When the transaction is aborted the message entry is then not put back into this.pedingAcks, so any subsequent ACK/NACK will find pendingAck==null, therefore acked==false, raising an exception.

        Attachments

          Activity

            People

            • Assignee:
              tabish Timothy A. Bish
              Reporter:
              mgerstel Markus Gerstel
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: