Uploaded image for project: 'ActiveMQ .Net'
  1. ActiveMQ .Net
  2. AMQNET-335

MessageConsumer does not Rollback on Exception

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • None
    • 1.5.2, 1.6.0
    • ActiveMQ
    • None

    Description

      For modes of AutoAcknowledgeEach, AutoAcknowledgeBatch & IndividualAcknowledge, Dispatch method is missing a call to Rollback() when listener throws an exception.

      Java version is doing this correctly but the .net version does not have that call.

      http://activemq.2283324.n4.nabble.com/Apache-NMS-ActiveMQ-MessageConsumer-bug-td3566206.html

      Because of this, messages don't get properly nacked nor will they get into a DLQ correctly.

      Java Code:

      } catch (RuntimeException e) {
      	LOG.error(getConsumerId() + " Exception while processing message: " + md.getMessage().getMessageId(), e);
      	if (isAutoAcknowledgeBatch() || isAutoAcknowledgeEach() || session.isIndividualAcknowledge()) {
      	    // schedual redelivery and possible dlq processing
      	    md.setRollbackCause(e);
      	    rollback();
      	} else {
      	    // Transacted or Client ack: Deliver the
      	    // next message.
      	    afterMessageIsConsumed(md, false);
      	}
          }
      

      .Net version:

      catch(Exception e)
      {
      	if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
      	{
      		// Redeliver the message
      	}
      	else
      	{
      		// Transacted or Client ack: Deliver the next message.
      		this.AfterMessageIsConsumed(dispatch, false);
      	}
      
      	Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e);
      
      	// If aborted we stop the abort here and let normal processing resume.
      	// This allows the session to shutdown normally and ack all messages
      	// that have outstanding acks in this consumer.
      	if( (Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested)
      	{
      		Thread.ResetAbort();
      	}
      }
      

      Think the solution is to call Rollback().

      catch(Exception e)
      {
      	if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
      	{
      	    // Redeliver the message
      	    Rollback(); // this takes care of checking the RedeliveryCounter and nacking when necessary
      	}
      	else
      	{
      		// Transacted or Client ack: Deliver the next message.
      		this.AfterMessageIsConsumed(dispatch, false);
      	}
      
      	Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e);
      
      	// If aborted we stop the abort here and let normal processing resume.
      	// This allows the session to shutdown normally and ack all messages
      	// that have outstanding acks in this consumer.
      	if( (Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested)
      	{
      		Thread.ResetAbort();
      	}
      }
      
      

      Attachments

        Activity

          People

            tabish Timothy A. Bish
            rasitha1 Rasitha Wijesinghe
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: