12 Replies Latest reply on May 25, 2006 6:43 PM by Ed cooper

    Fails to commit transaction

    Ed cooper Newbie

      Playing around with the default example queue, I thought I would try to commit a transaction of sends. I decided to break it with Ctrl-C, and it has never worked since. Tried server reboot, still no luck. Does anybody know the status of transactional support?

      import java.util.ResourceBundle;

      import javax.jms.ConnectionFactory;
      import javax.jms.JMSException;
      import javax.jms.QueueConnectionFactory;
      import javax.jms.QueueConnection;
      import javax.jms.QueueSession;
      import javax.jms.QueueSender;
      import javax.jms.QueueReceiver;
      import javax.jms.Queue;
      import javax.jms.Message;
      import javax.jms.TextMessage;
      //Import the classes to use JNDI.
      import javax.naming.*;

      public class JbossJmsSend {

      /**
      * Main method.
      *
      * @param args not used
      *
      */

      public static void main(String[] args) {

      ResourceBundle rb = ResourceBundle.getBundle("jndi");
      QueueSession myQSess=null;
      QueueConnection conn=null;
      try {

      InitialContext iniCtx = new InitialContext();
      ConnectionFactory cf = (ConnectionFactory) iniCtx.lookup("/ConnectionFactory");
      QueueConnectionFactory myQConnFactory = (QueueConnectionFactory) cf;
      conn = myQConnFactory.createQueueConnection();

      //myQSess = conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
      myQSess = conn.createQueueSession(true,-1);
      //QueueSession myQSess = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

      Queue myQueue = (Queue) iniCtx.lookup("/queue/testQueue");

      //Create a QueueSender message producer.
      QueueSender myQueueSender = myQSess.createSender(myQueue);

      //Create and send a message to the queue.
      TextMessage myTextMsg = myQSess.createTextMessage();
      int i=0;
      for (i=1; i<=100; i++)
      {
      myTextMsg.setText("Hello Mantech-IST from Ed Chwalik: msg_ID = " + i);
      //System.out.println("Sending Message: " + myTextMsg.getText());
      myQueueSender.send(myTextMsg);
      if (i%10==0)
      {
      System.out.println("Total sent messages = " + i);
      myQSess.commit();
      } }
      i--;
      System.out.println("Total sent messages = " + i);
      //session.commit();

      //Create a QueueReceiver message consumer.
      //QueueReceiver myQueueReceiver = myQSess.createReceiver(myQueue);

      //Start the QueueConnection created in step 3.
      conn.start();

      //Receive a message from the queue.
      //Message msg = myQueueReceiver.receive();

      //Retreive the contents of the message.
      //TextMessage txtMsg = (TextMessage) msg;
      //System.out.println("Read Message: " + txtMsg.getText());

      //myQSess.close();
      //conn.close();


      } catch (Exception jmse) {
      System.out.println("Exception occurred : " + jmse.toString());
      jmse.printStackTrace();
      }

      //Close the session and connection resources.

      finally{
      try {
      myQSess.close();
      } catch (JMSException e) {
      // TODO Auto-generated catch block
      //e.printStackTrace();
      }
      try {
      conn.close();
      } catch (JMSException e) {
      // TODO Auto-generated catch block
      //e.printStackTrace();
      }
      // wnat to close sessions here!
      }

      }
      }

        • 1. Re: Fails to commit transaction
          Ed cooper Newbie

          Here is the console output, just in case any developers are online:

          log4j:WARN No appenders could be found for logger (org.jboss.remoting.transport.PortUtil).
          log4j:WARN Please initialize the log4j system properly.
          Total sent messages = 10
          Exception occurred : org.jboss.jms.util.MessagingTransactionRolledBackException: Transaction was rolled back.
          org.jboss.jms.util.MessagingTransactionRolledBackException: Transaction was rolled back.
          at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.sendTransaction(ServerConnectionEndpoint.java:406)
          at org.jboss.jms.server.endpoint.advised.ConnectionAdvised.org$jboss$jms$server$endpoint$advised$ConnectionAdvised$sendTransaction$aop(ConnectionAdvised.java:99)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:585)
          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
          at org.jboss.jms.server.container.ServerLogInterceptor.invoke(ServerLogInterceptor.java:105)
          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
          at org.jboss.aop.Advisor.dynamicInvoke(Advisor.java:723)
          at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:101)
          at org.jboss.jms.server.remoting.JMSServerInvocationHandler.invoke(JMSServerInvocationHandler.java:126)
          at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:831)
          at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:680)
          at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:414)
          at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:498)
          at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:240)
          at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
          at org.jboss.remoting.Client.invoke(Client.java:527)
          at org.jboss.remoting.Client.invoke(Client.java:490)
          at org.jboss.jms.client.delegate.DelegateSupport.invoke(DelegateSupport.java:112)
          at org.jboss.jms.client.delegate.ClientConnectionDelegate$sendTransaction_N4986868250254447300.invokeNext(ClientConnectionDelegate$sendTransaction_N4986868250254447300.java)
          at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:130)
          at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:117)
          at org.jboss.jms.client.delegate.ClientConnectionDelegate$sendTransaction_N4986868250254447300.invokeNext(ClientConnectionDelegate$sendTransaction_N4986868250254447300.java)
          at org.jboss.jms.client.container.ExceptionInterceptor.invoke(ExceptionInterceptor.java:69)
          at org.jboss.jms.client.delegate.ClientConnectionDelegate$sendTransaction_N4986868250254447300.invokeNext(ClientConnectionDelegate$sendTransaction_N4986868250254447300.java)
          at org.jboss.jms.client.container.ClientLogInterceptor.invoke(ClientLogInterceptor.java:107)
          at org.jboss.jms.client.delegate.ClientConnectionDelegate$sendTransaction_N4986868250254447300.invokeNext(ClientConnectionDelegate$sendTransaction_N4986868250254447300.java)
          at org.jboss.jms.client.delegate.ClientConnectionDelegate.sendTransaction(ClientConnectionDelegate.java)
          at org.jboss.jms.tx.ResourceManager.commitLocal(ResourceManager.java:152)
          at org.jboss.jms.client.container.TransactionAspect.handleCommit(TransactionAspect.java:97)
          at org.jboss.aop.advice.org.jboss.jms.client.container.TransactionAspect7.invoke(TransactionAspect7.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:130)
          at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:117)
          at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
          at org.jboss.jms.client.container.ExceptionInterceptor.invoke(ExceptionInterceptor.java:69)
          at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
          at org.jboss.jms.client.container.ClientLogInterceptor.invoke(ClientLogInterceptor.java:107)
          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:165)
          at JbossJmsSend.main(JbossJmsSend.java:57)

          • 2. Re: Fails to commit transaction
            Tim Fox Master

            Sorry, I do not understand what you expected to see, and what you actually saw.

            Please explain in more detail.

            • 3. Re: Fails to commit transaction
              Ed cooper Newbie

              Thank you ofr the reply

              I changed the queue session to use transactions by setting the first arguemnt to be "true". I also follow the send with a commit call. This should allow me to commit or roll back a batch of sends to the queue.

              This is what I did when using MQ series/Web Sphere MQ when I wanted to use transactions.

              I expected to send 10 messages, then commit them. then, send ten more and commit them, until I reach 100 messages. However, I hit an exception on the commit, and instead of commiting the first ten messages, they were rolled back and the application bailed.

              Of coarse, when I read from the queue, nothing was there.

              • 4. Re: Fails to commit transaction
                Tim Fox Master

                You need to look in your server log file to see why the commit is failing.

                • 5. Re: Fails to commit transaction
                  Ed cooper Newbie

                  I am beginning to think that the default Hypersonic DB does not support transactions?

                  The log was purged just before running the application, and it generated a new server log with 2338 lines in it. These are huge log files. It will take some time to see what is relevant. There are several lines with this in it:

                  2006-05-22 10:26:33,793 DEBUG [org.jboss.mx.loading.RepositoryClassLoader] setRepository, repository=org.jboss.mx.loading.HeirarchicalLoaderRepository3@36d047, cl=org.jboss.mx.loading.HeirarchicalLoaderRepository3$CacheClassLoader@17b2712{ url=null ,addedOrder=0}
                  2006-05-22 10:26:33,793 DEBUG [org.jboss.mx.loading.UnifiedClassLoader] New jmx UCL with url null

                  Then I see the exception where the batch fails:

                  java.sql.BatchUpdateException: failed batch
                  at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
                  at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
                  at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:487)
                  at org.jboss.messaging.core.plugin.JDBCPersistenceManager.handleBeforeCommit1PC(JDBCPersistenceManager.java:2650)
                  at org.jboss.messaging.core.plugin.JDBCPersistenceManager$TransactionCallback.beforeCommit(JDBCPersistenceManager.java:4331)
                  at org.jboss.messaging.core.tx.Transaction.commit(Transaction.java:171)
                  at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.sendTransaction(ServerConnectionEndpoint.java:390)
                  at org.jboss.jms.server.endpoint.advised.ConnectionAdvised.org$jboss$jms$server$endpoint$advised$ConnectionAdvised$sendTransaction$aop(ConnectionAdvised.java:99)
                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                  at java.lang.reflect.Method.invoke(Method.java:585)
                  at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
                  at org.jboss.jms.server.container.ServerLogInterceptor.invoke(ServerLogInterceptor.java:105)
                  at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  at org.jboss.aop.Advisor.dynamicInvoke(Advisor.java:723)
                  at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:101)
                  at org.jboss.jms.server.remoting.JMSServerInvocationHandler.invoke(JMSServerInvocationHandler.java:126)
                  at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:831)
                  at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:680)
                  at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:414)
                  at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:498)
                  at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:240)




                  • 6. Re: Fails to commit transaction
                    Tim Fox Master

                    Certainly HSQL support for transactions is very basic (see getting started guide), however I am not sure that is your problem.

                    Can you try turning batch updates off (see getting started guide section 5.2.3) - this should give you a more descriptive error message.


                    Thanks.

                    • 7. Re: Fails to commit transaction
                      Ed cooper Newbie

                      Looks like that was it, cannot commit batches. Commiting one at a time is OK, anything more than that, and an exception is thrown. My example code above was just modified to commit right after the send. That code should work right out of the box for anyone interested.

                      Tim, thanks for your patience and help.

                      I am pretty excited that JBoss provides a JMS implementation, and plan to excercise its capabilities, hopefully to incorporate it into a project.

                      • 8. Re: Fails to commit transaction
                        Ed cooper Newbie

                        We are still experiencing strange behavior with transactions. Put in a couple messages, and everything works, put in a couple hundred thousand, and forget it. The write, as mentioned above, seems to work as long as you commit for each message. Use a messgae listener, and the process will fail after a few thousand reads.

                        What I am finding, is that JBoss does not seem to work very well out of the box, and really needs to be configured with another database. Reading the threads, this seems to be the way to go. I will post my listen code.

                        • 9. Re: Fails to commit transaction
                          Ed cooper Newbie



                          //Import the JMS API classes.
                          import javax.jms.ConnectionFactory;
                          import javax.jms.MessageListener;
                          import javax.jms.QueueConnectionFactory;
                          import javax.jms.QueueConnection;
                          import javax.jms.QueueSession;
                          import javax.jms.QueueSender;
                          import javax.jms.QueueReceiver;
                          import javax.jms.Queue;
                          import javax.jms.Session;
                          import javax.jms.Message;
                          import javax.jms.TextMessage;
                          //Import the classes to use JNDI.
                          import javax.naming.*;
                          import javax.swing.JOptionPane;

                          import com.sun.messaging.jms.JMSException;

                          import java.util.*;

                          public class JbossJmsListen {

                          /**
                          * Main method.
                          *
                          * @param args not used
                          *
                          */
                          public static int i = 0;
                          static QueueSession myQSess;
                          //public QueueSession myQSess=null;

                          public static void main(String[] args) {

                          ResourceBundle rb = ResourceBundle.getBundle("jndi");

                          long time = 0;
                          QueueConnection myQConn=null;
                          myQSess=null;

                          try {

                          InitialContext iniCtx = new InitialContext();
                          ConnectionFactory cf = (ConnectionFactory) iniCtx.lookup("/ConnectionFactory");
                          QueueConnectionFactory myQConnFactory = (QueueConnectionFactory) cf;
                          myQConn = myQConnFactory.createQueueConnection();

                          myQSess = myQConn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
                          //myQSess = myQConn.createQueueSession(true,-1);
                          //QueueSession myQSess = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

                          Queue myQueue = (Queue) iniCtx.lookup("/queue/testQueue");

                          time = System.currentTimeMillis();

                          // IMPORTANT: Receive calls will be blocked if the connection is
                          // not explicitly started, so make sure that we do so!
                          //Step 9:
                          //Start the QueueConnection created in step 3.
                          myQConn.start();

                          //Step 8:
                          //Create a QueueReceiver message consumer.
                          QueueReceiver myQueueReceiver = myQSess.createReceiver(myQueue);

                          // register a listener
                          System.out.println("registering message listener for messages");
                          MyListener listener1 = new MyListener(1);

                          myQueueReceiver.setMessageListener(listener1);

                          System.out.println("starting listener connection");

                          //Thread.sleep(5000); // give the receivers time to print messages
                          JOptionPane.showMessageDialog(null, "Click to stop listening");

                          } catch (JMSException je) {
                          System.err.println("caught " + je);
                          Exception e = je.getLinkedException();
                          if (e != null) {
                          System.err.println("subexception: " + e);
                          }

                          } catch (Exception e) {
                          System.err.println("caught " + e);

                          } finally {
                          if (myQSess != null) {
                          try {
                          System.out.println("closing session");
                          //myQSess.rollback();
                          myQSess.close();
                          } catch (javax.jms.JMSException e) {
                          // TODO Auto-generated catch block
                          System.err.println("caught " + e);
                          e.printStackTrace();
                          }
                          }
                          if (myQConn != null) {
                          try {
                          System.out.println("closing connection");
                          myQConn.close();
                          } catch (javax.jms.JMSException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                          System.err.println("connection.close() threw " + e);
                          }
                          }
                          }
                          }


                          /*
                          * This class provides the message listener.
                          */
                          static class MyListener implements MessageListener {
                          // an id to allow us to distinguish between different instances
                          int id;

                          MyListener(int id) {
                          this.id = id;
                          }


                          /**
                          * This method provides the implementation of the MessageListener
                          * interface.
                          */
                          public void onMessage(Message message) {
                          String body;

                          try {
                          // DEBUG used to remove binary messages
                          //myQSess.commit();
                          //System.out.println("in onMessage() of listener ");

                          if (message instanceof TextMessage) {
                          // display the message contents
                          body = ((TextMessage) message).getText();
                          //myQSess.rollback();
                          //myQSess.commit();

                          if (body != null) {
                          System.out.println("message contained: '" + body + "'");
                          i++;
                          } else {
                          System.out.println("error: message contained no body");
                          }
                          // display the message 'colour' property
                          // String colour = message.getStringProperty("colour");
                          // if (colour == null) {
                          // System.out.println("the message didn't have a colour property!");
                          // } else {
                          // System.out.println("colour="+colour);
                          // }
                          } else {
                          System.out.println("error: message was not a TextMessage as expected");

                          System.out.println(message);

                          if (message instanceof Message)
                          {
                          String msg_type = message.getJMSType();
                          System.out.println("JMS Message Type = " + msg_type );
                          }
                          }

                          } catch (JMSException je) {
                          System.out.println("onMessage caught " + je);
                          Exception e = je.getLinkedException();
                          if (e != null) System.out.println("linked exception: " + e);

                          } catch (Exception e) {
                          System.out.println("onMessage caught " + e);
                          }
                          }

                          }

                          }

                          • 10. Re: Fails to commit transaction
                            Tim Fox Master

                             

                            "edc" wrote:
                            We are still experiencing strange behavior with transactions. Put in a couple messages, and everything works, put in a couple hundred thousand, and forget it. The write, as mentioned above, seems to work as long as you commit for each message. Use a messgae listener, and the process will fail after a few thousand reads.



                            Why do you need to sent 100000 messages in a transaction? That is a huge number.

                            Also why do you need to receive the messages transactionally?

                            Not sure what you're trying to achieve here.

                            Can you explain your use case in more detail please.



                            What I am finding, is that JBoss does not seem to work very well out of the box, and really needs to be configured with another database. Reading the threads, this seems to be the way to go. I will post my listen code.


                            HSQL *should not* be used for production use. This is stated very clearly in the wiki and the documentation.
                            Also JBoss does not support HSQL use in production.
                            HSQL is bundled as a simple database to get you going in development, it should never be used in production.
                            Much as we'd like to bundle an Oracle database with the distribution you can imagine there would be licencing issues with doing that ;)





                            • 11. Re: Fails to commit transaction
                              Tim Fox Master

                              There is a section here about why HSQL is not appropriate for anything other than lightweight development http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigJBossMQDB

                              • 12. Re: Fails to commit transaction
                                Ed cooper Newbie

                                Thanks again for the reply, point taken about using HSQL.

                                As for my code, there is a commit after each read; therefor there is only one record to a transaction, the posted code shows this. What I am finding is that things just do not work if there are a lot of meesages in the queue with HSQL, which I shoudl not be using.

                                We plan to recnofigure JBoss MQ to use SQL server as the backend database. I am hoping the use of SQL server will take care of my issue. Should know something next week.