private boolean checkDeadlock(SQLException e, SqlRetryCallProperties properties) {
    if (databaseProduct.isDeadlock(e)) {
      if (properties.getDeadlockCount() > 0) {
        long waitInterval = deadlockRetryInterval * (ALLOWED_REPEATED_DEADLOCKS - properties.getDeadlockCount());
        LOG.warn("Deadlock detected in {}. Will wait {} ms try again up to {} times.", 
            properties.getCaller(), waitInterval, properties.getDeadlockCount());
        // Pause for a just a bit for retrying to avoid immediately jumping back into the deadlock.
        try {
          Thread.sleep(waitInterval);
        } catch (InterruptedException ie) {
          Thread.currentThread().interrupt();
          // NOP
        }
        return true;
      } else {
        LOG.error("Too many repeated deadlocks in {}, giving up.", properties.getCaller());
      }
    }
    return false;
  }
Executes the passed {@link SqlRetryFunction} and automatically retries the execution in case of failure. If there is
a retry-call upper in the call hierarchy, {@link SqlRetryCallProperties#withRetryPropagation } can be used to 
control wether to join it or create a nested retry-call.
@param properties {@link SqlRetryCallProperties} instance used to fine-tune/alter the execution-mechanism.
@param function The {@link SqlRetryFunction} to execute.
@return Returns with the result of the execution of the passed {@link SqlRetryFunction}.
@param <Result> Type of the result
@throws MetaException Thrown in case of execution error.
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/retry/SqlRetryHandler.java