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