0 Replies Latest reply on Jun 9, 2017 4:21 PM by camilla.g.martins

    MDB stops processing other messages after error occur in one message

    camilla.g.martins

      To simplify the problem I've configured an MDB with only one session.

       

       

        import javax.annotation.Resource;
          import javax.ejb.ActivationConfigProperty;
          import javax.ejb.MessageDriven;
          import javax.ejb.MessageDrivenContext;
          import javax.ejb.TransactionAttribute;
          import javax.ejb.TransactionAttributeType;
          import javax.inject.Inject;
          import javax.jms.Message;
          import javax.jms.MessageListener;
          import javax.jms.TextMessage;
      
      
          import org.slf4j.Logger;
      
      
          @TransactionAttribute(TransactionAttributeType.REQUIRED)
          @MessageDriven(activationConfig = {
          @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/adwordsReportRequest"),
          @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
          @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "veiculo = 'adwords'"),
          @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1"),
          @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "7500") })
          
          public class ReportRequestReceiveDispatcherAdwords implements MessageListener {
      
      
           @Resource
           private MessageDrivenContext mdc;
      
      
           @Inject
           private Logger logger;
      
      
           private Integer count = 0;
      
      
           public ReportRequestReceiveDispatcherAdwords() {
           // TODO Auto-generated constructor stub
           }
      
      
           public void onMessage(Message inMessage) {
           TextMessage msg = null;
           String text = null;
           try {
           if (inMessage instanceof TextMessage) {
      
      
           msg = (TextMessage) inMessage;
           text = msg.getText();
      
      
           if (count >= 10 && count <= 100) {
           logger.error("Count: {} - {} -  Marcando como erro!", ++count, text);
           throw new RuntimeException("teste de erro");
           } else
           logger.info("Count: {} - {}", ++count, text);
      
      
           } else {
           logger.warn("Message of wrong type: " + inMessage.getClass().getName());
           }
           } catch (Exception e) {
      
      
           mdc.setRollbackOnly();
           }
      
      
           }
      
      
          }
      

       

      The Queue is configured with 3 attempts and 2 minutes of delay between them.

       

      <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-delivery-attempts="3" redelivery-delay="120000" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
      

       

       

      Executing this code with 600 messages in the queue:

       

          14:10 --> it stopped the processing at the first error.
          14:12 --> processes 3 messages and stops.
          14:14 --> processes 10 messages and stops.
          14:16 --> processes 14 messages and stops.
          14:18 --> processes 10 messages and stops.
          14:20 --> processes 16 messages and stops.
          14:22 --> processes 9 messages and stops.
          14:24 --> processes 8 messages and stops.
          14:26 --> processes 7 messages and stops.
          14:28 --> processes 6 messages and stops.
          14:30 --> processes 6 messages and stops.
          14:32 --> processes 6 messages and stops.
          14:34 --> It goes out of the loop that generates error, so it finish the processing of the other messages until the queue is empty.
      

       

       

       

      Why the MDB stops if still there is messages in the queue? When a message comes back to the queue after a rollback, it goes to the top blocking te rest? I couldn't find any doc where this behavior is described.

       

      According to this doc:

      Other subsequent messages will be delivery regularly, only the cancelled message will be sent asynchronously back to the queue after the delay.

      https://activemq.apache.org/artemis/docs/2.0.0/undelivered-messages.html