private <Result> Result executeWithRetryInternal(SqlRetryCallProperties properties, SqlRetryFunction<Result> function) 
      throws TException {
    LOG.debug("Running retry function:" + properties);

    try {
      return function.execute();
    } catch (DataAccessException | SQLException e) {
      SQLException sqlEx = null;
      if (e.getCause() instanceof SQLException) {
        sqlEx = (SQLException) e.getCause();
      } else if (e instanceof SQLException) {
        sqlEx = (SQLException) e;
      }      
      if (sqlEx != null) {
        if (checkDeadlock(sqlEx, properties)) {
          properties.setDeadlockCount(properties.getDeadlockCount() - 1); 
          return executeWithRetryInternal(properties, function);
        }
        if (checkRetryable(sqlEx, properties)) {
          properties.setRetryCount(properties.getRetryCount() - 1);
          return executeWithRetryInternal(properties, function);
        }
      }
      LOG.error("Execution failed for caller {}", properties, e);
      throw new MetaException("Failed to execute function: " + properties.getCaller() + ", details:" + e.getMessage());
    } catch (MetaWrapperException e) {
      //unwrap and re-throw
      LOG.error("Execution failed for caller {}", properties, e.getCause());
      throw (MetaException) e.getCause();
    }
  }
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