1 2 Previous Next 17 Replies Latest reply: May 15, 2012 12:04 PM by jomu78 RSS

Message order after MDB rollback

jomu78 Newbie

Hi,

 

I am trying to asure the message order for all messages. I have read many topics in documenation and here in the community but it seems I missed something. All tests are running on Jboss 7.0.2  (preview, HornetQ 2.2.7)

 

As a producer I have a simple timer, which queues a message every fiew seconds - the text message includes current date.  There is one MDB as consumer which tries to post the message to another server so I can to this server to simulate unavailibility.

 

The produces uses message grouping:

 

textMessage.setStringProperty("JMSXGroupID", "Group1");

 

 

The consumer MDB is limited to one

@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")

 

The messaging system in Jboss 7.0.2 is set as follows

  • persist = true
  • redlivery-delay=30000
  • max-delivery-attempts=-1

 

JMS Connection Factories, sender uses XAConnectionFactory at the moment, but ConnectionFactory showed the same result

 

<jms-connection-factories>
    <connection-factory name="InVmConnectionFactory">
        <connectors>
            <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
            <entry name="java:/ConnectionFactory"/>
        </entries>
        <consumer-window-size>0</consumer-window-size>
    </connection-factory>
    <connection-factory name="InVmConnectionFactoryXA">
        <connectors>
            <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
            <entry name="java:/XAConnectionFactory"/>
        </entries>
        <consumer-window-size>0</consumer-window-size>
    </connection-factory>
    <pooled-connection-factory name="hornetq-ra">
        <connectors>
            <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
            <entry name="java:/JmsXA"/>
        </entries>
        <transaction mode="xa"/>
        <consumer-window-size>0</consumer-window-size>
    </pooled-connection-factory>
</jms-connection-factories>

 

From what I understood it would be ok to set consumer-window-size=0 for hornetq-ra only as the MDB as the only consumer uses this one - but anyway, it is not working.

 

If I shutdown the receiving server for a while, I can see in the logfile the server rolls back the transaction, as the message could not be posted. What confuses me a bit, that I see the log entries from the MDB when the timer created a new message even the first message in the queue could not be delivered and is waiting for the redelivery timer.

 

At the end when I check the log file (on JBoss and on the second server) I can see the timestamps are mixed. The first successful delivery (restart of server 2) was from 16:59:27,206 - the stdout is from the timer object.

 

16:59:29,251 INFO  [JMSListenerMessageDrivenBean] (Thread-0 (group:HornetQ-client-global-threads-466366777)) Message sent successfully: Eventmessage created on Mon May 14 16:58:25 CEST 2012
16:59:30,220 INFO  [stdout] (pool-5-thread-1) Message queued: Eventmessage created on Mon May 14 16:59:30 CEST 2012
16:59:30,220 INFO  [JMSListenerMessageDrivenBean] (Thread-1 (group:HornetQ-client-global-threads-466366777)) Message sent successfully: Eventmessage created on Mon May 14 16:59:30 CEST 2012
16:59:32,125 INFO  JMSListenerMessageDrivenBean] (Thread-0 (group:HornetQ-client-global-threads-466366777)) Message sent successfully: Eventmessage created on Mon May 14 16:59:00 CEST 2012
16:59:34,249 INFO  JMSListenerMessageDrivenBean] (Thread-1 (group:HornetQ-client-global-threads-466366777)) Message sent successfully: Eventmessage created on Mon May 14 16:58:30 CEST 2012

 

The above logfiles show both issues I have found

1st: It seems as a newly created message from 16:59:30 (2nd line) is sent directly (line 3) instead of queing it first - so it bypassses the older messages.

2nd: the old messages themselfs are out of order, message from 16:59:00 (line 4) is sent before 16:58:30 (line 5).

 

The output on the receiving server shows the same message oder as in th Jboss log.

 

So in summary I have

  • message groups which should asure messages are deliverd to same consumer
  • only one MDB as a consumer on the queue
  • disabled the cache on the connectors

 

 

What did I miss?

 

Regards

Joern

  • 1. Re: Message order after MDB rollback
    Andy Taylor Master

    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")

    This configures the number of sessions feeding the MDB not the MDB pool size, try setting the pool size to 0 also

  • 2. Re: Message order after MDB rollback
    jomu78 Newbie

    I added

     

    @ActivationConfigProperty(propertyName = "MaxPoolSize", propertyValue = "0")
    

     

     

    but still same result:

     

    19:20:50,071 INFO  [JMSListenerMessageDrivenBean] (Thread-3 (group:HornetQ-client-global-threads-1386935250)) Message sent successfully: Eventmessage created on Mon May 14 19:20:50 CEST 2012
    19:20:55,046 INFO  [stdout] (pool-7-thread-1) Message queued: Eventmessage created on Mon May 14 19:20:55 CEST 2012 
    19:20:55,061 INFO  [JMSListenerMessageDrivenBean] (Thread-0 (group:HornetQ-client-global-threads-1386935250)) Message sent successfully: Eventmessage created on Mon May 14 19:20:55 CEST 2012
    19:20:57,169 INFO  [JMSListenerMessageDrivenBean] (Thread-3 (group:HornetQ-client-global-threads-1386935250)) Message sent successfully: Eventmessage created on Mon May 14 19:20:25 CEST 2012
    
    
    
  • 3. Re: Message order after MDB rollback
    Andy Taylor Master

    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")

    No this is correct, I mean this is *not* the setting to configure the MDB pool size, you need to do this in separate configuration on the MDB configuration.

  • 4. Re: Message order after MDB rollback
    Justin Bertram Master

    You can set the size of the instance pool by annotating your MDB with something like this:

     

    @org.jboss.ejb3.annotation.Pool(value="my-singleton-pool")
    

     

    Then in your standalone*.xml add the pool:

     

    <pools>
        <bean-instance-pools>
            <strict-max-pool name="my-singleton-pool" max-pool-size="1" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
            ...
        </bean-instance-pools>
    </pools>
    
  • 5. Re: Message order after MDB rollback
    jomu78 Newbie

    A bit better, but still not correct.

     

    11:34:45,117 INFO  [JMSListenerMessageDrivenBean] (Thread-0 (group:HornetQ-client-global-threads-327695711)) Message sent successfully: Eventmessage created on Tue May 15 11:34:15 CEST 2012
    11:34:50,037 INFO  [stdout] (pool-5-thread-1) Message queued: Eventmessage created on Tue May 15 11:34:50 CEST 2012
    11:34:50,045 INFO  [JMSListenerMessageDrivenBean] (Thread-0 (group:HornetQ-client-global-threads-327695711)) Message sent successfully: Eventmessage created on Tue May 15 11:34:50 CEST 2012
    11:34:52,090 INFO  [JMSListenerMessageDrivenBean] (Thread-1 (group:HornetQ-client-global-threads-327695711)) Message sent successfully: Eventmessage created on Tue May 15 11:34:20 CEST 2012
    

     

    The queued messages (< 11.34:45) are sent in correct order, but newly created messages (>=11:34:50) are still sent directly. So new messages are also in correct order but still old and new are mixed.

  • 6. Re: Message order after MDB rollback
    Andy Taylor Master

    can you explain in detail, client code, server code, configuration etc what you are doing please.

  • 7. Re: Message order after MDB rollback
    jomu78 Newbie

    I removed the post to the second server and replaced it by output only. It is a quite easy test - a @schedule timed operation creates a message every 5 seconds. The consumer MDB listening on the queue outputs the message - in case a file $home/test.rollback exists, the MDB rolls back instead of consuming

     

     

    @Override
    public void onMessage(Message msg) {
      try {
        TextMessage textMessage = (TextMessage) msg;
        String text = textMessage.getText();
        if (testFile.exists()) {
          ejbContext.setRollbackOnly();
          logger.log(Level.INFO, "Rolled back message {0}", text);
        } else {    
          logger.log(Level.INFO, "Message delivered   {0}", text);
        }
      } catch (JMSException ex) {
        logger.log(Level.SEVERE, "Exception occured: {0}", ex);
      }
    }
    

     

    Address-Settings

     

    <address-settings>
        <address-setting match="jms.queue.testQueue">
            <redelivery-delay>
                30000
            </redelivery-delay>
            <max-size-bytes>
                20971520
            </max-size-bytes>
            <page-size-bytes>
                10485760
            </page-size-bytes>
            <message-counter-history-day-limit>
                10
            </message-counter-history-day-limit>
            <address-full-policy>
                PAGE
            </address-full-policy>
            <max-delivery-attempts>
                -1
            </max-delivery-attempts>
        </address-setting>
    </address-settings>
    

     

    Pools

     

     <pools>
        <bean-instance-pools>
            <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
            <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
            <strict-max-pool name="mdb-singleton-pool" max-pool-size="1" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
        </bean-instance-pools>
    </pools>
    

     

    The MDB is annotated with

     

    @Pool(value = "mdb-singleton-pool")
    @MessageDriven(name = "JMSListenerMessageDrivenBean",
    activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/test"),
        @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1") // only one session feeding the mdb
    })
    

     

    I try to configure connector factory without cache, but server removes the config line after restart

     

    <connection-factory name="InVmConnectionFactory">
        <connectors>
            <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
            <entry name="java:/ConnectionFactory"/>
        </entries>
        <!-- disable cache for correct message order -->
        <consumer-window-size>0</consumer-window-size>
    </connection-factory>
    

     

    Same for XAConnectionFactory and hornetq-ra

  • 8. Re: Message order after MDB rollback
    Andy Taylor Master

    its because you are using a redelievry delay which is non deterministic.

  • 9. Re: Message order after MDB rollback
    jomu78 Newbie

    You mean I should set the redelivery delay to 0 and add a Thread.sleep to my MDB (otherwise log files get spammed) !?

    I have teted it , and it worked - but is there no better way to so - I do not like Therad.sleep in the application

  • 10. Re: Message order after MDB rollback
    Andy Taylor Master

    Im not sure why you need Thread.sleep()

  • 11. Re: Message order after MDB rollback
    jomu78 Newbie

    We are logging if the message is undelivered, also the receiver may do. This would cause a lot of entries in the log files....

  • 12. Re: Message order after MDB rollback
    Andy Taylor Master

    not sure i follow, what difference does the sleep make?

  • 13. Re: Message order after MDB rollback
    jomu78 Newbie

    the new rollback block is now as follows:

     

    ejbContext.setRollbackOnly();
    logger.log(Level.INFO, "Rolled back message {0}", text);                                
    logger.info ("Start sleeping");
    Thread.sleep (15000);
    logger.info ("Awaken");
    

     

    So in case the message cannot be delivered we are waiting 15 seconds; so the failed delivery takes at least 15 seconds and the log entries are not spammed into the logfile. As written - it works - but I do not like it.

  • 14. Re: Message order after MDB rollback
    Andy Taylor Master

    again, I dont understand why you want to sleep, what issue are you seeing if you dont sleep

1 2 Previous Next