public static <T> T executeWithRetry(SQLCommand<T> cmd, PreparedStatement stmt,
      long baseWindow, int maxRetries)  throws SQLException {

    T result = null;

    // retry with # of maxRetries before throwing exception
    for (int failures = 0; ; failures++) {
      try {
        result = cmd.run(stmt);
        return result;
      } catch (SQLTransientException e) {
        LOG.warn("Failure and retry # {}", failures, e);
        if (failures >= maxRetries) {
          throw e;
        }
        long waitTime = getRandomWaitTime(baseWindow, failures,
            ThreadLocalRandom.current());
        try {
          Thread.sleep(waitTime);
        } catch (InterruptedException iex) {
         }
      } catch (SQLException e) {
        // throw other types of SQLExceptions (SQLNonTransientException / SQLRecoverableException)
        throw e;
      }
    }
  }
Retry SQL execution with random backoff (same as the one implemented in HDFS-767).
This function only retries when the SQL query throws a SQLTransientException (which
might be able to succeed with a simple retry). It doesn't retry when the exception
is a SQLRecoverableException or SQLNonTransientException. For SQLRecoverableException
the caller needs to reconnect to the database and restart the whole transaction.

@param cmd the SQL command
@param stmt the prepared statement of SQL.
@param baseWindow  The base time window (in milliseconds) before the next retry.
see {@link #getRandomWaitTime} for details.
@param maxRetries the maximum # of retries when getting a SQLTransientException.
@throws SQLException throws SQLRecoverableException or SQLNonTransientException the
first time it is caught, or SQLTransientException when the maxRetries has reached.
ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java