7 Replies Latest reply on Jul 9, 2008 3:41 AM by timfox

    Queue MaxSize Not Obeyed When Using Transacted Sessions


      Hi,

      I wanted to check with you first before I file a bug.

      With a non-transacted session, I try to send
      200 messages to an empty queue with MaxSize
      set to 20 and on the 21st message, I get a
      JMSException and the final state of the queue
      shows 20 messages. This is exactly what I
      expect.

      However, with a transacted session, I do the
      same thing, starting with an empty queue,
      with my client program and I get
      all 200 messages to show up in my queue -
      no JMSException. I would have expected 0
      messages to have persisted on the queue
      since the limit is set to 20.

      Would someone please explain this behavior
      if it is a feature?

      If it is a bug, please let me know and I will
      file it (as soon as I know the proper procedure
      to do that).

      Thanks,
      Vishal

      P.S. I am using JBoss Messaging 1.4.0.SP3 running
      in JBoss 4.2.2 GA.

        • 1. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions
          ataylor

          You'll probably find you aren't committing your transaction, add a session.commit() and you'll see the exception thrown.

          • 2. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions

             

            "ataylor" wrote:
            You'll probably find you aren't committing your transaction, add a session.commit() and you'll see the exception thrown.


            Hi Andy,

            Thanks for the response.

            I am doing a session.commit() and I am seeing the output that shows this
            in my code:

            
             // Start sending messages
             sendLoop(session, producer);
            
             if (transacted)
             {
             System.err.println("About to commit the session.");
             session.commit();
             System.err.println("Finished commiting the session.");
             }
             System.out.println("Done.");
            
            
            
            



            Here's the interesting thing:

            With 0 messages in the queue and MaxSize=20, the transaction
            of 200 messages is allowed to commit:


            
            ...
            ...
            Sending message: 188
            Sending message: 189
            Sending message: 190
            Sending message: 191
            Sending message: 192
            Sending message: 193
            Sending message: 194
            Sending message: 195
            Sending message: 196
            Sending message: 197
            Sending message: 198
            Sending message: 199
            About to commit the session.
            Finished commiting the session.
            Done.
            
            We have reached the finally block.
            About to close JMS connection.
            Finished closing the JMS connection.
            
            


            With 200 messages in the queue and MaxSize=20, the transaction
            of 200 messags is NOT allowed to commit:

            
            
            ...
            ...
            ...
            Sending message: 199
            About to commit the session.
            Caught: org.jboss.jms.exception.MessagingTransactionRolledBackException: Failed to route Reference[3246080]:RELIABLE to FR.SYNC.RESPONSE
            org.jboss.jms.exception.MessagingTransactionRolledBackException: Failed to route Reference[3246080]:RELIABLE to FR.SYNC.RESPONSE
             at org.jboss.jms.tx.ResourceManager.commitLocal(ResourceManager.java:228)
             at org.jboss.jms.client.container.SessionAspect.handleCommit(SessionAspect.java:557)
             at org.jboss.aop.advice.org.jboss.jms.client.container.SessionAspect26.invoke(SessionAspect26.java)
             at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
             at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:170)
             at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:105)
             at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
             at org.jboss.jms.client.delegate.ClientSessionDelegate.commit(ClientSessionDelegate.java)
             at org.jboss.jms.client.JBossSession.commit(JBossSession.java:164)
             at ProducerJBM.run(ProducerJBM.java:122)
             at ProducerJBM.main(ProducerJBM.java:42)
            Caused by: javax.jms.JMSException: Failed to route Reference[3246080]:RELIABLE to FR.SYNC.RESPONSE
             at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.sendMessage(ServerConnectionEndpoint.java:743)
             at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.processTransaction(ServerConnectionEndpoint.java:792)
            
            
            


            I'm wondering if the first case here is a bug or a feature.

            Thanks,
            Vishal

            • 3. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions
              ataylor

              So i would expect the first to fail as well, I tested this and it failed ok for me. Can you post your test so I can see exactly what you are doing

              • 4. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions

                Hello Andy,

                The test for the first case involves using HermesJMS to look at the queue
                and make sure it is empty. And then running the following code:


                
                
                import java.util.Date;
                import java.util.Properties;
                
                
                import java.io.IOException;
                
                import javax.jms.Connection;
                import javax.jms.DeliveryMode;
                import javax.jms.Destination;
                import javax.jms.MessageProducer;
                import javax.jms.Session;
                import javax.jms.TextMessage;
                import javax.naming.Context;
                import javax.naming.InitialContext;
                
                /**
                 * A simple tool for publishing messages
                 *
                 * @version $Revision: 1.2 $
                 */
                
                public class ProducerJBM
                {
                
                 private Destination destination;
                 private int messageCount;
                 private long sleepTime;
                 private boolean verbose = true;
                 private int messageSize;
                 private long timeToLive;
                 private String queueName;
                 private String providerURL;
                 private String connectionFactoryBinding;
                 private boolean transacted;
                
                
                 /**************************************************************************/
                 public static void main(String[] args)
                 {
                 ProducerJBM producer = new ProducerJBM();
                 producer.run();
                 }
                 /**************************************************************************/
                 public ProducerJBM()
                 {
                 Properties props = new Properties();
                 try
                 {
                 props.load(this.getClass().getClassLoader().getResourceAsStream("jbm.properties"));
                 }
                 catch (IOException ioe)
                 {
                 System.err.println("Error loading jbm.properties.");
                 ioe.printStackTrace(System.err);
                 System.exit(-1);
                 }
                
                 providerURL = props.getProperty("provider_url");
                 messageCount = Integer.parseInt(props.getProperty("num_messages_to_send"));
                 if (messageCount == -1)
                 messageCount = Integer.MAX_VALUE;
                 queueName = props.getProperty("queue_name");
                 messageSize = Integer.parseInt(props.getProperty("message_size"));
                 sleepTime = Long.parseLong(props.getProperty("producer.sleep_time_ms"));
                 connectionFactoryBinding = props.getProperty("connection_factory_binding");
                 transacted = Boolean.parseBoolean(props.getProperty("producer.transacted").trim());
                 }
                 /**************************************************************************/
                 public void run()
                 {
                 Connection connection = null;
                
                 try
                 {
                 // System.out.println("Connecting to URL: " + url);
                 System.out.println("Publishing a Message with size "
                 + messageSize + " to queue" + ": "
                 + queueName);
                 System.out.println("Sleeping between publish " + sleepTime + " ms");
                 if (timeToLive != 0) {
                 System.out.println("Messages time to live " + timeToLive + " ms");
                 }
                
                 Properties props = new Properties();
                 props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
                 props.setProperty(Context.PROVIDER_URL, providerURL);
                 props.setProperty(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
                
                
                 javax.naming.Context ctx = new InitialContext(props);
                
                 javax.jms.ConnectionFactory factory =
                 (javax.jms.ConnectionFactory)ctx.lookup(connectionFactoryBinding);
                
                 connection = factory.createConnection();
                
                 connection.start();
                
                 // Create the session
                 Session session = connection.createSession(
                 transacted,
                 Session.AUTO_ACKNOWLEDGE);
                 System.err.println("Session transaction mode: " + transacted);
                
                 destination = session.createQueue(queueName);
                
                 // Create the producer.
                 MessageProducer producer = session.createProducer(destination);
                 producer.setDeliveryMode(DeliveryMode.PERSISTENT);
                
                 if (timeToLive != 0) {
                 producer.setTimeToLive(timeToLive);
                 }
                
                 // Start sending messages
                 sendLoop(session, producer);
                
                 if (transacted)
                 {
                 System.err.println("About to commit the session.");
                 session.commit();
                 System.err.println("Finished commiting the session.");
                 }
                 System.out.println("Done.");
                
                 }
                 catch (Exception e)
                 {
                 System.out.println("Caught: " + e);
                 e.printStackTrace();
                 }
                 finally
                 {
                 System.err.println();
                 System.err.println("We have reached the finally block.");
                 try
                 {
                 System.err.println("About to close JMS connection.");
                 connection.close();
                 System.err.println("Finished closing the JMS connection.");
                 }
                 catch (Throwable ignore)
                 {
                 }
                 }
                 }
                 /**************************************************************************/
                 protected void sendLoop(Session session, MessageProducer producer)
                 throws Exception
                 {
                
                 for (int i = 0; i < messageCount || messageCount == 0; i++)
                 {
                 /*if (i == 20)
                 throw new Exception("This is an intentionl test exception thrown by Vishal");*/
                 TextMessage message = session.createTextMessage(i+"");
                
                 String msg = message.getText();
                 System.out.println("Sending message: " + msg);
                 message.setJMSMessageID("ID:"+messageCount);
                 message.setJMSCorrelationID("JMS CID:"+messageCount);
                 producer.send(message);
                
                
                 Thread.sleep(sleepTime);
                
                 }
                 }
                 /**************************************************************************/
                }
                
                
                
                




                Here is my jbm.properties file. It's used by a few different
                client programs, but I post it here in its entirety for the sake
                of not smudging the evidence ;) For the sake of the current
                issue we are discussing, I am only running the above client
                program.


                provider_url = jnp://162.10.170.78:1399
                
                connection_factory_binding = ConnectionFactory
                
                queue_name = FR.SYNC.RESPONSE
                num_messages_to_send = 200
                message_size = 255
                
                
                producer.sleep_time_ms = 10
                
                
                consumer.sleep_time_ms = 100
                
                
                producer.transacted = true
                consumer.transacted = true
                
                
                consumer.even.num_threads = 4
                consumer.even.sleep_time_ms = 1000
                
                consumer.odd.num_threads = 4
                consumer.odd.sleep_time_ms = 1000
                
                



                I run the program, notice that it has completed successfully
                (no exception) and then notice in HermesJMS that 200 messages
                show up.

                All this time, I have confirmed that MaxSize==20 in JBoss JMX
                MBean page for the queue.

                Thanks,
                Vishal

                • 5. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions
                  timfox

                  This looks like a bug to me. I can see in the code that the max size check is not being made when the transaction commits.

                  • 6. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions


                    This looks like a bug to me. I can see in the code that the max size check is not being made when the transaction commits.
                    


                    Thanks, Tim.

                    Let me know if you will file a bug or want me to file it. Please
                    include a link to instructions if you want me to file it as I am
                    not aware of the procedures JBoss uses.

                    Best,
                    Vishal

                    • 7. Re: Queue MaxSize Not Obeyed When Using Transacted Sessions
                      timfox