1 2 Previous Next 22 Replies Latest reply on Oct 7, 2010 9:33 PM by Clebert Suconic

    Message Delivery Order on MDB Rollback (Cancel)

    Joe Mihalich Newbie

        Hi,

       

          I saw a few topics on this through search, but none really addressed the issue I'm seeing.

       

          I am trying to test the message order functionality, because I don't see any type of behavior documented in the docs.

       

          My test case is this:

       

             - I have a JMS topic, with 2 consumers (both MDB's with durable subscriptions).  We're running in Jboss 4.2.3, in EJB 2.1 land, CMT.

             - MDB1 is coded to just receive and log each message it gets and return.

             - MDB2 is coded to setRollbackOnly the first time it ever receives a message, and then for every subsequent call will receive, and log the message successfully and return like MDB1 does.

             - I published 4 messages to the topic from a client that is external to the app server (publishing code is below), to the topic, through JNDI lookup.  We'll call these messages MSG1, MSG2, MSG3, MSG4, and they are published in that order.

             - I have redelivery delay set to <redelivery-delay>10000</redelivery-delay> 10 seconds.

             - I am not using message grouping.

       

         I ran this test 3 times:

       

         My Results:

       

         Test Run 1:

         1) MDB1 got the msgs in order: MSG1, MSG2, MSG3, MSG4

         2) MDB2 got MSG1 and rolled back the transaction.  Then 10 seconds later, MSG4 came in.  Immediately following I received MSG3, MSG2, and then MSG1 in that order.

       

         Test Run 2:

         1) MDB1 got the msgs in order: MSG1, MSG2, MSG3, MSG4

         2) MDB2 got MSG1 and rolled back the transaction.  Then 10  seconds later, MSG2 came in.  Immediately following I received MSG4, MSG3, and then MSG1 in that order.

       

         Test Run 3:

         1) MDB1 got the msgs in order: MSG1, MSG2, MSG3, MSG4

         2) MDB2 got MSG1 and rolled back the transaction.  Then 10   seconds later, MSG4 came in.  Immediately following I received MSG2,  MSG3, and then MSG1 in that order.

       

         So, I have some questions:

       

         1) I thought the redelivery delay was only applied to the message that failed.  Why are NO messages being redelivered for 10 seconds?

       

              I have since run a slightly different test to try and see what was going on here.  In this second test case, I published 2 messages (MSG1, MSG2), closed the JMS session, opened a new session, and published 2 more messages (MSG3, and MSG4).  When I did this, MDB2 got MSG1 and rolled back.  But a second later (roughly) in this case, MDB2 got MSG3 and MSG4.  Then 10 seconds after MSG1 came in, I got:  MSG2, then MSG1 came in again.

       

             Why are we seeing different behavior here?

       

         2) I would be expecting MDB2 to get messages in the following order: MSG1 (fail), MSG2, MSG3, MSG4, after 10 seconds MSG1 (succeed).  Why are all the messages after MSG1 coming in, in what seems like a random order?

       

               I understand this is perhaps irrelevant, but JBoss Messaging 1.4.x, and Websphere MQ work the way i described above where everything comes in, in the order published, following the failed message.  Also, the jboss-messaging redelivery delay only applied to the failed message. messages behind the failed message were delivered immediately.

       

               I also understand things get complicated if multiple messages start rolling back.  But in this simple case, I'd expect messages to be in order after the first one failed.

       

               hornetq config file is attached.

       

               Here is the code I used to publish for an external client:

       

                   InitialContext ctx = getContext(mqProviderType, providerUrl);
                 
                  TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup(connectionFactory);
                  Topic topic = (Topic)ctx.lookup(topicName);
                 
                  connection = factory.createTopicConnection();
                  session = ((TopicConnection)connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
                 
                  publisher = ((TopicSession)session).createPublisher(topic);
                 
                  for (int index=0; index < messages.length; index++)
                  {
                      Message message = messages[index];
                     
                      TextMessage textMessage = session.createTextMessage();
                      populateTextMessage(message, textMessage);
                      publisher.publish(textMessage);
                  }

       

       

       

       

          Thanks for the help.

          Joe

        • 1. Re: Message Delivery Order on MDB Rollback (Cancel)
          Clebert Suconic Master

          If you need strict ordering, disable caching at the client by setting consumerWindowSize = 0. There are a few other threads around this.

           

          The client will cache messages, the redelivery will go back to the server however the client will first exaust the previous-delivered messages to the client before it can get the redelivered messages.

          • 2. Re: Message Delivery Order on MDB Rollback (Cancel)
            Joe Mihalich Newbie

              oh, ok, I'll screw around with that.

             

              In the mean time, can we address the redelivery delay issue I mentioned, and what the inteded behavior is?  I got 2 different behaviors based on how i published messages.

             

            Thanks,

            Joe

            • 3. Re: Message Delivery Order on MDB Rollback (Cancel)
              Joe Mihalich Newbie

              Ok, so I set <consumer-window-size>0</consumer-window-size> on the connection factory in the hornetq-jms.xml file.

               

              The messages are still coming out of order:

               

              Publish: MSG1, MSG2, MSG3, MSG4.

               

              Receive: MSG1 (fail), 10 seconds later, MSG1 (this is correct), MSG4, MSG2, MSG3

               

              Is what you would expect?

               

                Thanks,

              Joe

              • 4. Re: Message Delivery Order on MDB Rollback (Cancel)
                Clebert Suconic Master

                You have to set it on the Resource adapter. The resource adapter has its own setting.

                 

                Now I'm a bit confused on how you do at your environment.

                • 5. Re: Message Delivery Order on MDB Rollback (Cancel)
                  Clebert Suconic Master

                  If you were doing EJB3 you would be setting your activation properties (for the inbound connection).

                   

                  I remember there's something about activation properties also on EJB2. I'm pretty sure you will remember that.. let me know if you don't

                   

                  On JCA you have the outbound CF (the one you use at the JmsXA lookup) and you have the inbound properties (that will be use on the MDB activation)

                  • 6. Re: Message Delivery Order on MDB Rollback (Cancel)
                    Clebert Suconic Master
                    In the mean time, can we address the redelivery delay issue I mentioned, and what the inteded behavior is?  I got 2 different behaviors based on how i published messages.

                     

                     

                    There's another feature request around pausing the whole deliver for some time (I can't remember the ID now).

                     

                    If you do redeliver, the message will go back to the tail and the other messages will be immediately delivered (what won't work if you require strict ordering).

                    • 7. Re: Message Delivery Order on MDB Rollback (Cancel)
                      Andy Taylor Master

                      also remember that the MDB's will be in a pool, the default is 15 i think, therefore there will be 15 consumers receiving and rolling back messages in parallel.

                      • 8. Re: Message Delivery Order on MDB Rollback (Cancel)
                        Joe Mihalich Newbie

                        Andy Taylor wrote:

                         

                        also remember that the MDB's will be in a pool, the default is 15 i think, therefore there will be 15 consumers receiving and rolling back messages in parallel.

                         

                           Hi,

                         

                             Let me clarify my configuration.  My JMS inflow adapter is configured as follows:

                         

                        <invoker-proxy-binding>
                              <name>message-driven-bean</name>
                              <invoker-mbean>default</invoker-mbean>
                              <proxy-factory>org.jboss.ejb.plugins.inflow.JBossJMSMessageEndpointFactory</proxy-factory>
                              <proxy-factory-config>
                                <activation-config>
                                   <activation-config-property>
                                      <activation-config-property-name>providerAdapterJNDI</activation-config-property-name>
                                      <activation-config-property-value>DefaultJMSProvider</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>minSession</activation-config-property-name>
                                      <activation-config-property-value>1</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>maxSession</activation-config-property-name>
                                      <activation-config-property-value>1</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>keepAlive</activation-config-property-name>
                                      <activation-config-property-value>60000</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>maxMessages</activation-config-property-name>
                                      <activation-config-property-value>1</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>reconnectInterval</activation-config-property-name>
                                      <activation-config-property-value>10</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>useDLQ</activation-config-property-name>
                                      <activation-config-property-value>true</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>DLQHandler</activation-config-property-name>
                                      <activation-config-property-value>org.jboss.resource.adapter.jms.inflow.dlq.GenericDLQHandler</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>DLQJNDIName</activation-config-property-name>
                                      <activation-config-property-value>queue/DLQ</activation-config-property-value>
                                   </activation-config-property>
                                   <activation-config-property>
                                      <activation-config-property-name>DLQMaxResent</activation-config-property-name>
                                      <activation-config-property-value>10</activation-config-property-value>
                                   </activation-config-property>
                                </activation-config>
                                <endpoint-interceptors>
                                  <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
                                  <interceptor>org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor</interceptor>
                                  <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                                  <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                                </endpoint-interceptors>
                              </proxy-factory-config>
                            </invoker-proxy-binding>

                         

                            I have the number of sessions max'd at 1, which means there is only 1 thread processing messages for each MDB I have coded (I have two.  two subscribers to the one topic).  So in effect, each of my MDB's are single threaded.

                         

                            The only functionality I need is this:

                         

                            Msg Publish Order: MSG1, MSG2, MSG3, MSG4

                            Redelivery Delay: 10 seconds

                         

                            Msg Delivery Order:

                            MSG1 (Fails)

                            MSG2 (succeed)

                            MSG3 (succeed)

                            MSG4 (succeed)

                            MSG1 (redelivered after 10 seconds).

                         

                            My only question is why, after MSG1 fails, do messages not come in, in the order received?  They come in, in a random order, and that doesn't make any sense.

                         

                            Regarding the earlier post, you said that the consumer window size has to be put on the JCA inflow side.  Does that mean for EJB2 I would add a consumer-window-size attribute to the invoker-proxy-binding above?

                         

                            Thanks,

                            Joe

                        • 9. Re: Message Delivery Order on MDB Rollback (Cancel)
                          Joe Mihalich Newbie

                          lol! I got it.

                           

                          I added this to the invoker-proxy-binding like I just suggested:

                           

                                    <activation-config-property>
                                        <activation-config-property-name>consumerWindowSize</activation-config-property-name>
                                        <activation-config-property-value>0</activation-config-property-value>
                                     </activation-config-property>

                           

                             Now everything came in, in the exact order I needed.

                           

                             Joe

                          • 10. Re: Message Delivery Order on MDB Rollback (Cancel)
                            Tim Fox Master

                            What order do you expect the messages to arrive in?

                             

                            Have you verified the behaviour with a standard JMS consumer? (I.e. not using an MDB)

                            • 11. Re: Message Delivery Order on MDB Rollback (Cancel)
                              Joe Mihalich Newbie

                                I haven't tested redelivery with a standard JMS consumer.  I assume the behavior will be the same with the configuration I have working now.

                               

                                So, I have only one question left then.

                               

                                Why is it that setting consumerWindowSize on invoker-proxy-binding worked.  But, setting it on the connection factory in the hornetq-jms.xml file (as specified in the docs) doesn't work?

                               

                                Thanks,

                                Joe

                              • 12. Re: Message Delivery Order on MDB Rollback (Cancel)
                                Andy Taylor Master

                                Joe Mihalich wrote:

                                 

                                  I haven't tested redelivery with a standard JMS consumer.  I assume the behavior will be the same with the configuration I have working now.

                                 

                                  So, I have only one question left then.

                                 

                                  Why is it that setting consumerWindowSize on invoker-proxy-binding worked.  But, setting it on the connection factory in the hornetq-jms.xml file (as specified in the docs) doesn't work?

                                 

                                  Thanks,

                                  Joe

                                Are you saying that setting it oin the hornetq-jms.xml file didnt work for your MDB. i would expect that as this is not used by the RA

                                • 13. Re: Message Delivery Order on MDB Rollback (Cancel)
                                  Joe Mihalich Newbie

                                     Yes, that is why I was saying.

                                   

                                     Can you explain more about specifically what is not used by the resource adapter so I know this going forward?  Are you saying none of the connection factory definitions are used by the resource adapter, or only specific properties you can set on the connection factory are ignored?

                                   

                                     Or point me to where in the documentation I can read so I can stop being so confused.

                                   

                                     Thanks,

                                     Joe

                                  • 14. Re: Message Delivery Order on MDB Rollback (Cancel)
                                    Clebert Suconic Master

                                    The Resource adapter has its own connection mechanism for inbound, so it won't use the regular connetion factory. For MDBs you have to configure it at the invoker (JCA inbound)

                                    1 2 Previous Next