Package com.sun.messaging.jmq.jmsserver.persist.jdbc

Source Code of com.sun.messaging.jmq.jmsserver.persist.jdbc.Util$RetryStrategy

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

/*
* @(#)Util.java  1.42 08/17/07
*/

package com.sun.messaging.jmq.jmsserver.persist.jdbc;

import com.sun.messaging.jmq.util.log.Logger;
import com.sun.messaging.jmq.jmsserver.Globals;
import com.sun.messaging.jmq.jmsserver.BrokerStateHandler;
import com.sun.messaging.jmq.jmsserver.Broker;
import com.sun.messaging.jmq.jmsservice.BrokerEvent;
import com.sun.messaging.jmq.jmsserver.resources.*;
import com.sun.messaging.jmq.jmsserver.persist.HABrokerInfo;
import com.sun.messaging.jmq.jmsserver.persist.jdbc.comm.CommDBManager;
import com.sun.messaging.jmq.jmsserver.util.BrokerException;
import com.sun.messaging.jmq.jmsserver.util.StoreBeingTakenOverException;
import com.sun.messaging.jmq.io.MQObjectInputStream;
import com.sun.messaging.jmq.util.log.Logger;

import java.io.*;
import java.sql.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
* Contains utility functions.
* - methods to set/get Object
* - methods to generate SQL statements
*/
public class Util implements DBConstants {

    /**
     * Added support for setting String parameter to NULL.
     */
    static void setString( PreparedStatement pstmt, int pos, String value )
        throws SQLException {

        if ( value != null && value.length() > 0 ) {
            pstmt.setString( pos, value );
        } else {
            pstmt.setNull( pos, Types.VARCHAR );
        }
    }

    /**
     * Added support for setting int parameter to NULL.
     */
    static void setInt( PreparedStatement pstmt, int pos, int value )
        throws SQLException {

        if ( value >= 0 ) {
            pstmt.setInt( pos, value );
        } else {
            pstmt.setNull( pos, Types.INTEGER );
        }
    }

    /**
     * Added support for setting long parameter to NULL.
     */
    static void setLong( PreparedStatement pstmt, int pos, long value )
        throws SQLException {

        if ( value >= 0 ) {
            pstmt.setLong( pos, value );
        } else {
            pstmt.setNull( pos, Types.BIGINT );
        }
    }

    static void setObject(PreparedStatement pstmt, int pos, Object obj)
  throws IOException, SQLException {

        if ( obj == null ) {
            pstmt.setNull( pos, Types.LONGVARBINARY );
        } else {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
            ObjectOutputStream bos = new ObjectOutputStream(baos);
            bos.writeObject(obj);
            bos.close();

            byte[] buf = baos.toByteArray();
            setBytes(pstmt, pos, buf);
        }
    }

    public static void setBytes(PreparedStatement pstmt, int pos, byte[] data)
  throws IOException, SQLException {

        if (data == null) {
            pstmt.setNull( pos, Types.LONGVARBINARY );
        } else {
            pstmt.setBytes(pos, data);
        }
    }

    static void setBytesAsBinaryStream(PreparedStatement pstmt, int pos, byte[] data)
  throws IOException, SQLException {

        if (data == null) {
            pstmt.setNull( pos, Types.LONGVARBINARY );
        } else {
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            pstmt.setBinaryStream(pos, bais, data.length);
            bais.close();
        }
    }

    static Object readObject(ResultSet rs, int pos)
  throws IOException, SQLException, ClassNotFoundException {

  InputStream is = rs.getBinaryStream(pos);

        // If column is empty then InputStream will be NULL
        if (is == null) {
            return null;
        }

        // Use our version of ObjectInputStream so we can load old
        // serialized object from an old store, i.e. store migration
        ObjectInputStream ois = new MQObjectInputStream(is);
  Object obj = ois.readObject();
  ois.close();
  return obj;
    }

    public static byte[] readBytes(ResultSet rs, int pos)
  throws IOException, SQLException {

  InputStream is = rs.getBinaryStream(pos);

        // If column is empty then InputStream will be NULL
        if (is == null) {
            return null;
        }

  ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);

  // read until either:
  //   returned number of bytes is 0 or -1: no more to read
  //   get an eof
  byte[] buf = new byte[1024];
  while (true) {
      try {
    int cnt = is.read(buf, 0, 256);
    if (cnt > 0) {
       bos.write(buf, 0, cnt);
    } else {
       // cnt = 0 or -1; cannot read anything, we are done
       break;
    }
      } catch (EOFException e) {
    // done
    break;
      }
  }

  return bos.toByteArray();
    }

    /**
     * SQL statement to insert Destination into IMQDEST35.
     */
    static int insertDstDIDIndex = 1;
    static int insertDstDestIndex = 2;

    static String getInsertDestinationSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TDEST_CDID + ", "
      + TDEST_CDEST + ") VALUES ( ?,? )";
    }

    /**
     * SQL statement to insert a message and related info into IMQMSG35.
     */
    static int insertMsgMIDIndex = 1;
    static int insertMsgDIDIndex = 2;
    static int insertMsgSizeIndex = 3;
    static int insertMsgMsgIndex = 4;

    static String getInsertMessageSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TMSG_CMID + ", "
      + TMSG_CDID + ", "
      + TMSG_CMSGSIZE + ", "
      + TMSG_CMSG + ") VALUES ( ?,?,?,? )";

    }

    /**
     * SQL statement to delete consumer states of a message from
     * IMQILIST35.
     */
    static int deleteStatesMIDIndex = 1;

    static String getDeleteStatesSQL(String table) {
  return "DELETE FROM " + table + " WHERE " +
      TINTSTATE_CMID + "=?";
    }

    /**
     * SQL statement to insert state of consumer w.r.t. a message into
     * IMQILIST35.
     */
    static int insertMsgStateMIDIndex = 1;
    static int insertMsgStateCUIDIndex = 2;
    static int insertMsgStateDIDIndex = 3;
    static int insertMsgStateStateIndex = 4;

    static String getInsertMessageStateSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TINTSTATE_CMID + ", "
      + TINTSTATE_CCUID + ", "
      + TINTSTATE_CDID + ", "
      + TINTSTATE_CSTATE + ") " + "VALUES ( ?,?,?,? )";
    }

    /**
     * SQL statement to insert Consumer into IMQINT35.
     */
    static int insertInterestCUIDIndex = 1;
    static int insertInterestIntIndex = 2;

    static String getInsertInterestSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TINT_CCUID + ", "
      + TINT_CINTEREST + ") VALUES ( ?,? )";
    }

    static PreparedStatement getPreparedStatement(Connection conn, String sql)
  throws BrokerException {

  try {
      return conn.prepareStatement(sql);
  } catch (SQLException e) {
      Globals.getLogger().log(Logger.ERROR,
                BrokerResources.X_PREPARE_DBSTMT_FAILED, sql, e);
      throw new BrokerException(Globals.getBrokerResources()
          .getString(BrokerResources.X_PREPARE_DBSTMT_FAILED, sql), e);
  }
    }

    /**
     * SQL statement to insert Transaction into IMQTXN35.
     */
    static int insertTxnTidIndex = 1;
    static int insertTxnStateIndex = 2;
    static int insertTxnStateObjIndex = 3;

    static String getInsertTxnSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TTXN_CTUID + ", "
      + TTXN_CSTATE + ", "
      + TTXN_CSTATEOBJ + ") VALUES ( ?,?,? )";
    }

    /**
     * SQL statement to insert TransactionAcknowledgement into IMQTACK35.
     */
    static int insertTxnAckTidIndex = 1;
    static int insertTxnAckAckIndex = 2;

    static String getInsertTxnAckSQL(String table) {
  return "INSERT INTO " + table + " ("
      + TTXNACK_CTUID + ", "
      + TTXNACK_CACK + ") VALUES ( ?,? )";
    }

    /**
     * SQL statement to insert configuration change record into IMQCCREC35.
     */
    static int insertCCRTimeIndex = 1;
    static int insertCCRRecordIndex = 2;

    static String getInsertConfigRecordSQL(String table) {
  return "INSERT INTO " + table + " ( "
      + TCONFIG_CTIME +", "
      + TCONFIG_CRECORD +") " + "VALUES ( ?,? )";
    }

    /**
     * SQL statement to insert property name/value pair into IMQPROPS35.
     */
    static int insertPropertyNameIndex = 1;
    static int insertPropertyValueIndex = 2;

    static String getInsertPropertySQL(String table) {
  return "INSERT INTO " + table + " ("
      + TPROP_CNAME + ", "
      + TPROP_CVALUE + ") VALUES ( ?,? )";
    }

    /**
     * This method must only be used by DB store of DBManager.java class
     *
     * @param rset
     * @param stmt
     * @param conn
     */
    public static void close( ResultSet rset, Statement stmt,
                              Connection conn, Throwable ex )
                              throws BrokerException {
         close(rset, stmt, conn, ex, null);
    }

    public static void close( ResultSet rset, Statement stmt,
                              Connection conn, Throwable ex,
                              CommDBManager mgrArg )
                              throws BrokerException {

        try {
            if ( rset != null ) {
                rset.close();
            }
            if ( stmt != null ) {
                stmt.close();
            }
        } catch ( SQLException e ) {
            throw new BrokerException(
                Globals.getBrokerResources().getKString(
                    BrokerResources.E_INTERNAL_BROKER_ERROR,
                    "Unable to close JDBC resources", e ) );
        } finally {
            if ( conn != null ) {
                if (mgrArg == null) {
                    DBManager.getDBManager().freeConnection( conn, ex );
                } else {
                   mgrArg.freeConnection( conn, ex );
                }
            }
        }
    }

    /**
     * Returns true if the string contains only alphanumeric characters and '_'.
     * @param str the string to check
     */
    public static boolean isAlphanumericString( String str ) {

        boolean isValid = false;
        if (str != null && str.length() > 0) {
            char c;
            for (int i = 0, len = str.length(); i < len; i++) {
                c = str.charAt(i);
                isValid = Character.isLetterOrDigit(c);
                // Also allow '_' char
                if (!isValid && c != '_') {
                    break;
                }
            }
        }

        return isValid;
    }

    /*
     * Methods to invoke Oracle LOB APIs using reflection because we don't
     * want to have a depedency on Oracle driver for our build environment!
     */

    static boolean OracleBLOB_initialized = false;
    static Method OracleBLOB_empty_lob_method = null;
    static Method OracleBLOB_getBinaryOutputStream_method = null;
    static Method OraclePreparedStatement_setBLOB_method = null;

    /**
     * Initalize methods for Oracle LOB APIs.
     * @throws BrokerException
     */
    static final void OracleBLOB_init()
        throws BrokerException {

        if ( !OracleBLOB_initialized ) {
            try {
                Class BLOBCls = Class.forName( "oracle.sql.BLOB" );

                OracleBLOB_empty_lob_method =
                    BLOBCls.getMethod( "empty_lob", null );

                Class[] paramTypes = { Integer.TYPE };

                OracleBLOB_getBinaryOutputStream_method =
                    BLOBCls.getMethod( "getBinaryOutputStream", null );

                Class OraclePreparedStatementCls = Class.forName(
                    "oracle.jdbc.OraclePreparedStatement" );

                paramTypes = new Class[2];
                paramTypes[0] = Integer.TYPE;
                paramTypes[1] = BLOBCls;
                OraclePreparedStatement_setBLOB_method =
                    OraclePreparedStatementCls.getMethod( "setBLOB", paramTypes );

                OracleBLOB_initialized = true;
            } catch ( Exception e ) {
                throw new BrokerException(
                    Globals.getBrokerResources().getKString(
                        BrokerResources.E_INTERNAL_BROKER_ERROR,
                        "Oracle LOB extension APIs not found" ), e );
            }
        }
    }

    /**
     * Invoke oracle.sql.BLOB.empty_lob() to create an empty LOB.
     *
     * Note:
     * Because an empty_lob() method creates a special marker that does not
     * contain a locator, a JDBC application cannot read or write to it.
     * The JDBC driver throws the exception ORA-17098 Invalid empty LOB
     * operation if a JDBC application attempts to read or write to an
     * empty LOB before it is stored in the database.
     */
    static final Blob OracleBLOB_empty_lob()
        throws Exception {

        if ( !OracleBLOB_initialized ) {
            OracleBLOB_init();
        }

        // An oracle.sql.BLOB object
        Blob blob = (Blob)OracleBLOB_empty_lob_method.invoke( null, null );

        return blob;
    }

    /**
     * Invoke oracle.sql.BLOB.getBinaryOutputStream()
     */
    static final OutputStream OracleBLOB_getBinaryOutputStream(
        Blob blob ) throws Exception {

        if ( !OracleBLOB_initialized ) {
            OracleBLOB_init();
        }

        OutputStream out = (OutputStream)
            OracleBLOB_getBinaryOutputStream_method.invoke( blob, null );

        return out;
    }

    /**
     * Invoke ((oracle.jdbc.OraclePreparedStatement)(pstmt)).setBLOB( pos, blob );
     */
    static void OraclePreparedStatement_setBLOB(
        PreparedStatement pstmt, int pos, Blob blob ) throws Exception {

        if ( !OracleBLOB_initialized ) {
            OracleBLOB_init();
        }

        Object[] arglist = new Object[2];
        arglist[0] = new Integer( pos );
        arglist[1] = blob;
        OraclePreparedStatement_setBLOB_method.invoke( pstmt, arglist );
    }

    /**
     * To set a Blob using Oracle driver, we need to do the following steps:
     *
     * BLOB blob = BLOB.empty_lob();
     * ((OraclePreparedStatement)(pstmt)).setBLOB( pos, blob );
     */
    static final Blob setOracleBLOB( PreparedStatement pstmt, int pos )
        throws Exception {

        Blob blob = null;
        blob = OracleBLOB_empty_lob();
        OraclePreparedStatement_setBLOB( pstmt, pos, blob );

        return blob;
    }

    /**
     * Returns true if the error is due to HADB running out of locks set:
     * HADB-E-02080: Too many locks set, out of request objects
     * HADB-E-02096: Too many locks held concurrently
     * @param t throwable object
     * @return true if HADB is running out of locks set
     */
    static boolean isHADBTooManyLockError( Throwable t ) {

        if ( t instanceof SQLException ) {
            SQLException e = (SQLException)t;
            int errorCode = e.getErrorCode();
            return (errorCode == 2080 || errorCode == 2096);
        }
        return false;
    }

    /**
     * A convenient method to break down the total number of rows to
     * delete/update into smaller chunks. This method assumes that the
     * specified resultset is ordered by the timestamp column.
     *
     * @param rs the ResultSet
     * @param tsColumnIndex the index of the timestamp column
     * @param chunkSize the number of rows
     * @return a List of timestamp to delimit each chunk
     * @throws SQLException
     */
    public static List getChunkDelimiters(ResultSet rs,
        int tsColumnIndex, int chunkSize) throws SQLException {

        ArrayList list = new ArrayList(10);
        int rowCount = 0;
        while (rs.next()) {
            if (++rowCount == chunkSize) {
                rowCount = 0;
                list.add(new Long( rs.getLong(tsColumnIndex) ));
            }
        }

        // Since more rows could potentially qualify at delete-time than at
        // select-time, the last chunk should include all records that might
        // be added 60 secs from now...
        list.add(new Long( System.currentTimeMillis() + 60000 ));

        return list;
    }

    /**
     * Class to encapsulate database transaction retry strategy.
     *
     * Using the default delay time of 2 secs and max number of retry of 5:
     *
     * Retry #     Delay Time     Total Time
     * -------     ----------     ----------
     * 1            2 secs          2 secs
     * 2            4 secs          6 secs
     * 3            8 secs         14 secs
     * 4           16 secs         30 secs
     * 5           32 secs         62 secs
     */
    public static class RetryStrategy {

        CommDBManager dbMgr = null;

        Exception originalException = null; // Original exception
        int retryCount = 0;                 // Keep track # retries
        int retryMax;                       // Max number of retry
        long delayTime;                     // Keep track of delay time

        public RetryStrategy() throws BrokerException {
            this( DBManager.getDBManager() );
        }

        // Bootstrap constructor
        public RetryStrategy( CommDBManager mgr ) {
            dbMgr = mgr;
            delayTime = mgr.txnRetryDelay;
            retryMax = mgr.txnRetryMax;
        }

        public RetryStrategy( CommDBManager mgr,
                              long retryDelay, int max ) {
            dbMgr = mgr;
            delayTime = retryDelay;
            retryMax = max;
        }

        /**
         * Assert if JDBC operation should be retry. This method will log and
         * re-throw the original exception if the operation should not be retry
         * or the retry count has reached the maximum number of retries.
         *
         * @param e the exception
         * @throws BrokerException
         */
        public void assertShouldRetry( Exception e ) throws BrokerException {

            // Save the original exception
            if ( originalException == null ) {
                originalException = e;
            }

            if ( e instanceof StoreBeingTakenOverException &&
                 Globals.getHAEnabled() ) {

                String msg = Globals.getBrokerResources().getKString(
                    BrokerResources.E_SPLIT_BRAIN );
                Globals.getLogger().logStack( Logger.ERROR, msg, e );

                Broker.getBroker().exit(BrokerStateHandler.getRestartCode(), msg,
                    BrokerEvent.Type.RESTART, e, true, false, true);

                // Re-throw the exception
                throw (StoreBeingTakenOverException)e;
            }

            Throwable cause = e;

            // Get cause of exception if it is wrapped in a BrokerException
            if ( e instanceof BrokerException ) {
                cause = e.getCause();
            }

            boolean retry = false// Assume operation cannot be retry

            if ( cause instanceof SQLException ) {
                SQLException ex = (SQLException)cause;
                int errorCode = ex.getErrorCode();
                String sqlState = ex.getSQLState();

                if ( dbMgr.isHADB() ) {
                    retry =
                        errorCode == 224        // The operation timed out
                        || errorCode == 2078    // Wrong dictionary version no
                        || errorCode == 2080    // Too many locks set
                        || errorCode == 2096    // Too many locks held concurrently
                        || errorCode == 2097    // Upgrade from shared to exclusive lock failed
                        || errorCode == 4576    // Client held transaction open for too long
                        || errorCode == 12815   // Table memory space exhausted
                        || errorCode == 25012   // Timed out waiting for reply from peer
                        || errorCode == 25017   // No connection to server
                        || errorCode == 25018   // Lost connection to the server
                        ;
                } else if ( dbMgr.isOracle() ) {
                    retry =
                        errorCode == 00020      // Maximum number of processes num exceeded
                        || errorCode == 00054   // Resource busy and acquire with NOWAIT specified
                        || errorCode == 17008   // Closed Connection
                        || errorCode == 17009   // Closed Statement
                        || errorCode == 17016   // Statement timed out
                        || errorCode == 12535   // TNS:operation timed out
                        ;
                } else if ( dbMgr.isMysql() ) {
                    String emsg = ex.getMessage();
                    retry =
                        errorCode == 1205       // Lock wait timeout exceeded; try restarting transaction
                        || errorCode == 1213    // Deadlock found when trying to get lock; try restarting transaction
                        || (emsg.trim().toLowerCase().contains("got temporary error") &&
                            emsg.trim().toLowerCase().contains("from ndb"))
                        || (emsg.trim().toLowerCase().contains("no operations allowed after connection closed"))
                        || (emsg.trim().toLowerCase().contains("lock wait timeout exceeded"));
                        ;
                } else if ( dbMgr.isDerby() ) {
                    retry =
                        sqlState.equals("40001") // deadlock
                        ;
                } else {
                    String msg = ex.getMessage();
                    retry = (msg != null) &&
                      (msg.toLowerCase().indexOf( "timed out" ) > 0);
                }
            }

            // Verify if we should retry the operation
            if ( retry && ( retryCount < retryMax ) ) {
                retryCount++;
                Globals.getLogger().log(Logger.INFO, Globals.getBrokerResources().getKString(
                    BrokerResources.I_RETRY_DB_OP, retryCount+","+delayTime, cause.getMessage()+
                    (cause instanceof SQLException ? "["+((SQLException)cause).getErrorCode()+
                    "]["+((SQLException)cause).getSQLState()+"]":"")));
                try {
                    Thread.sleep( delayTime );
                } catch (Exception ie) {}

                // Log error for debugging
                Globals.getLogger().logStack( Logger.DEBUG,
                    "Attempt to retry database operation due to unexpected error [retryCount="
                    + retryCount + ", delayTime=" + delayTime + "]", e );

                // Increase the retry delay by doubling it for each pass
                delayTime *= 2;

                return;
            }

            // Operation cannot be retry, so log & re-throw the original exception
            if ( !(originalException instanceof BrokerException) ) {
                // This shouldn't happen since DAO class suppose to wrap
                // all exception as BrokerException!!!
                originalException = new BrokerException(
                    Globals.getBrokerResources().getKString(
                        BrokerResources.E_INTERNAL_BROKER_ERROR,
                        "Unable to retry database operation" ), originalException );
            }

            throw (BrokerException)originalException;
        }
    }

    public static boolean isConnectionError(Throwable t, CommDBManager mgr) {
        Throwable cause = t;

        if (t instanceof com.sun.messaging.jmq.jmsserver.util.DestinationNotFoundException ||
            t instanceof com.sun.messaging.jmq.jmsserver.persist.TakeoverLockException ||
            t instanceof com.sun.messaging.jmq.jmsserver.util.StoreBeingTakenOverException ||
            t instanceof com.sun.messaging.jmq.jmsserver.util.TransactionAckExistException ||
            t instanceof com.sun.messaging.bridge.service.DupKeyException ||
            t instanceof com.sun.messaging.bridge.service.KeyNotFoundException) {
            return false;
        }

        if (t instanceof BrokerException) {
            cause = t.getCause();
        }

        if (!(cause instanceof SQLException)) {
            return false;
        }

        if (!mgr.isPoolDataSource()) {
            return true;
        }

        SQLException ex = (SQLException)cause;
        int eCode = ex.getErrorCode();
        String eMessage = ex.getMessage();
        String eSQLState = ex.getSQLState();

        if (mgr.isMysql()) {
            if (eMessage.contains("Communication link failure")) {
                return true;
            }
            if (eMessage.contains("No operations allowed after connection closed")) {
                return true;
            }
            if (eMessage.startsWith("Got temporary error") && eMessage.endsWith("from NDB")) {
                return true;
            }
            if (eCode == 1205 || eMessage.contains("Lock wait timeout exceeded")) {
                return true;
            }
        }

        if (eSQLState != null) {
            if (mgr.getSQLStateType() == DatabaseMetaData.sqlStateSQL99) {
                if (eSQLState.startsWith("08") ||
                    eSQLState.equals("01002") ||
                    eSQLState.equals("04501") ||
                    eSQLState.equals("HYT00") ||
                    eSQLState.equals("HYT01") ||
                    eSQLState.equals("S1T00")) {
                    return true;
                }
                return false;
            }
            if (mgr.getSQLStateType() == DatabaseMetaData.sqlStateXOpen) {
                if (eSQLState.startsWith("08")) {
                    return true;
                }
                return false;
            }
        }
        return false;
    }

    public static String brokerNotTakenOverClause(DBManager dbMgr) throws BrokerException {
        return (Globals.getHAEnabled() ?
                        " AND NOT EXISTS (" +
                        ((BrokerDAOImpl)dbMgr.getDAOFactory().getBrokerDAO())
                        .selectIsBeingTakenOverSQL + ")" : "");
    }

    public static void checkBeingTakenOver(Connection conn, DBManager dbMgr, Logger logger,
                                           java.util.logging.Logger logger_)
                                           throws BrokerException {
        if (!Globals.getHAEnabled()) return;

        String brokerID = dbMgr.getBrokerID();
        BrokerDAO dao = dbMgr.getDAOFactory().getBrokerDAO();
        if (dao.isBeingTakenOver(conn, brokerID)) {
            BrokerException be = new StoreBeingTakenOverException(
                                 Globals.getBrokerResources().getKString(
                                 BrokerResources.E_STORE_BEING_TAKEN_OVER));
            try {
                 HABrokerInfo bkrInfo = dao.getBrokerInfo(conn, brokerID);
                 String emsg = Globals.getBrokerResources().getKString(
                               BrokerResources.X_INTERNAL_EXCEPTION, bkrInfo.toString());
                 logger.log(Logger.ERROR, emsg, be);
                 logExt(logger_, java.util.logging.Level.SEVERE, emsg, be);
            } catch (Throwable t) { /* Ignore error */ }
            throw be;
        }
    }


    public static void logExt(java.util.logging.Logger logger_,
                              java.util.logging.Level level,
                              String emsg, Throwable t) {
        if (logger_ == null) return;
        if (t != null) {
            logger_.log(level, emsg, t);
        } else {
            logger_.log(level, emsg);
        }
    }
}
TOP

Related Classes of com.sun.messaging.jmq.jmsserver.persist.jdbc.Util$RetryStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.