3 Replies Latest reply on Apr 17, 2003 10:29 AM by adrian.brock

    tranzact enqueue so slowly to JDBCPersist

    hirotakanakano

      Hi

      I'm Japanese.
      sorry English is not good.

      I used JBoss 3.0.6. JMS System
      Queue is peristed to Oracle 9.0.1 DB

      2000 transaction enqueu with transaction mode
      is nessaly 2minutes.

      I viewed Source Code org.jboss.mq.pm.jdbc2.PersistenceManager.

      add messod called 2000times.
      It is means that SQL call over network is 2000times.
      it is cause enqueu slowlly.

      I think better that change 1time use SQL Call like under source whith addBatch JDBCstatement
      /////////////////////////////////////////////////////////////////////////////////
      //
      // Adding a message
      //
      /////////////////////////////////////////////////////////////////////////////////
      public void add(MessageReference messageRef[], org.jboss.mq.pm.Tx txId) throws javax.jms.JMSException
      {

      // LogInfo logInfo;
      TransactionManagerStrategy tms = new TransactionManagerStrategy();
      tms.startTX();
      Connection c = null;
      PreparedStatement insStmt = null;
      PreparedStatement markStmt = null;
      int i = 0;
      try
      {
      c = datasource.getConnection();
      insStmt = c.prepareStatement(INSERT_MESSAGE);

      markStmt = c.prepareStatement(MARK_MESSAGE);

      for(i= 0;i<messageRef.length;i++){
      // has it allready been stored by the message cache interface??
      if (messageRef.persistData!=null)
      {
      //update the stored record,
      markMessage(markStmt, messageRef
      .messageId, (String) messageRef.persistData, txId, "A");
      }
      else
      {
      SpyMessage message = messageRef
      .getMessage();
      add(insStmt, message, txId, "A");
      messageRef.setStored(((SpyDestination) message.getJMSDestination()).toString());
      }
      }
      insStmt.executeBatch() ;
      markStmt.executeBatch();

      }
      catch (IOException e)
      {
      tms.setRollbackOnly();
      throw new SpyJMSException("Could not store message: " + messageRef
      .messageId, e);
      }
      catch (SQLException e)
      {
      tms.setRollbackOnly();
      throw new SpyJMSException("Could not store message: " + messageRef.messageId, e);
      }
      finally
      {
      try
      {
      insStmt.close();
      }
      catch (Throwable ignore)
      {
      }
      try
      {
      markStmt.close();
      }
      catch (Throwable ignore)
      {
      }
      try
      {
      c.close();
      }
      catch (Throwable ignore)
      {
      }
      tms.endTX();
      }
      }

      please examine this code to Version 3.2.
      best regards.

        • 1. Re: tranzact enqueue so slowly to JDBCPersist

          There is no such method as
          add(MessageReference[], ...)

          The current implementation of the message cache
          would make this hard to implement.
          It does not guarantee (nor should it) that all
          messages for a transaction are held in memory.
          With lots of transactions/messages you would
          very quickly get an OutOfMemoryException

          Reliability is always more important than speed.

          Your idea is a good one though. It would be more
          optimal to persist the messages at transaction
          prepare/commit when memory is not an issue.

          Regards,
          Adrian

          • 2. Re: tranzact enqueue so slowly to JDBCPersist
            hirotakanakano

            Thanks your response.

            This sample code is change by me.

            I changed this code local and SpyXAResourceManager ,too.
            afer make jar.
            this code perfoms 1s process 2000tran .

            I understand transactions from client is held memory.

            This messege is sended by Queue client over sock network.
            (transactions hold message,ack list)

            This transactions is sended to Oracle by PersistanceManager .
            1 tran is proceed by SQL over network .

            this point is neck point.

            I change markMessage and add method like under code.

            public void markMessage(PreparedStatement stmt, long messageid, String destination, org.jboss.mq.pm.Tx txId, String mark)
            throws SQLException
            {

            // LogInfo logInfo;
            if (txId == null)
            {
            stmt.setNull(1, java.sql.Types.BIGINT);
            }
            else
            {
            stmt.setLong(1, txId.longValue());
            }
            stmt.setString(2, mark);
            stmt.setLong(3, messageid);
            stmt.setString(4, destination);
            stmt.addBatch();

            }

            I think that changes code more 100tran per 1 SQL over network(executeBatch)
            doesn't lost reliability and not occures OutOfMemory ?

            Regards,
            Adrian

            • 3. Re: tranzact enqueue so slowly to JDBCPersist

              You would actually make the OutOfMemory
              more likely.
              The 2000 message body contents are stored both in
              memory and in the statement's list of command
              to execute as blobs.
              Now multiply that by N clients doing the same thing.

              If you have a working example, post a patch
              to www.sf.net/projects/jboss

              Regards,
              Adrian