Bad use of Jms field JMSXDeliveryCount. Related to RedeliveryCount and message 
prefetch 
----------------------------------------------------------------------------------------

                 Key: AMQ-1730
                 URL: https://issues.apache.org/activemq/browse/AMQ-1730
             Project: ActiveMQ
          Issue Type: Bug
          Components: Broker
    Affects Versions: 5.1.0, 5.0.0
            Reporter: Alexis Kinsella


JMSXDeliveryCount  has to be incremented only on transactional delivery failure 
( RuntimeException on processing message, ... ).

JMSXDeliveryCount  is actualy used in correlation with Message.java field: 
'redeliveryCounter'.

But RedeliveryCounter  field is used to be incremented each time the message is 
preteched or sent to a consumer => It does not mean that message has been 
processed by business in transaction with a failure. It just has been 
prefetched by consumer ou subscriber. 
A 'not consumed message' can be give back to the broker when the consumer is 
closed by user, because it has been prefetched but not really consumed!

It does not match the meaning of the JMS field JMSXDeliveryCount  :
"If a failure occurs within transactional processing then the JMSXDeliveryCount 
is incremented".


JMSXDeliveryCount  field only has to be incremented on rollback (isn't it? ). 
This is why Message.redeliveryCount can not be used. Or the behavour of field 
Message.redeliveryCount has to be changed.

You can either :
* create a new counter on message incremented only on rollback, or
* modify classes : PrefetchSubscription.java and Queue.java to remove 
redeliveryCount increment and increment it only on rollback.


* PrefetchSubscription.java:

                    if (inAckRange) {
//                        node.incrementRedeliveryCounter();
                        if (ack.getLastMessageId().equals(messageId)) {
                            destination = node.getRegionDestination();
                            callDispatchMatched = true;
                            break;
                        }
                    }



* Queue.java:

                for (MessageReference ref : sub.remove(context, this)) {
                    QueueMessageReference qmr = (QueueMessageReference)ref;
//                    qmr.incrementRedeliveryCounter();
                    if( qmr.getLockOwner()==sub ) {
                        qmr.unlock();
//                        if (!qmr.isDropped() && !qmr.isAcked()) {
//                              qmr.incrementRedeliveryCounter();
//                        }
                    }
                    list.add(qmr);
                }


BTW, In this code it seems there is a second bug, in case of  test 
"qmr.getLockOwner()==sub" is true qmr is incremented a second time ?! Is it 
right ?



The result of this problem is the following: 

With Spring and DefaultMessageListenerContainer, a message is consumed one by 
one. This is why a message prefteched many times, on first real consuming has a 
JMSXDeliveryCount  with high value not reflecting the reality.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to