LockState lock(LockRequest lock, String queryId, boolean isBlocking, List<HiveLock> acquiredLocks) throws LockException {
    Objects.requireNonNull(queryId, "queryId cannot be null");
    nextSleep = 50;
    /*
     * get from conf to pick up changes; make sure not to set too low and kill the metastore
     * MAX_SLEEP is the max time each backoff() will wait for, thus the total time to wait for
     * successful lock acquisition is approximately (see backoff()) maxNumWaits * MAX_SLEEP.
     */
    MAX_SLEEP = Math.max(15000, conf.getTimeVar(HiveConf.ConfVars.HIVE_LOCK_SLEEP_BETWEEN_RETRIES, TimeUnit.MILLISECONDS));
    int maxNumWaits = Math.max(0, conf.getIntVar(HiveConf.ConfVars.HIVE_LOCK_NUMRETRIES));
    try {
      LOG.info("Requesting lock for queryId=" + queryId);
      LOG.debug("Requested lock= " + lock);
      LockResponse res = txnManager.getMS().lock(lock);
      //link lockId to queryId
      LOG.info("Response to queryId=" + queryId + " " + res);
      if(!isBlocking) {
        if(res.getState() == LockState.WAITING) {
          return LockState.WAITING;
        }
      }
      int numRetries = 0;
      long startRetry = System.currentTimeMillis();
      while (res.getState() == LockState.WAITING && numRetries++ < maxNumWaits) {
        backoff();
        LOG.debug("Starting retry attempt:#{} to acquire locks for lockId={}. QueryId={}",
                numRetries, res.getLockid(), queryId);
        res = txnManager.getMS().checkLock(res.getLockid());
      }
      long retryDuration = System.currentTimeMillis() - startRetry;
      DbHiveLock hl = new DbHiveLock(res.getLockid(), queryId, lock.getTxnid(), lock.getComponent());
      if(locks.size() > 0) {
        boolean logMsg = false;
        for(DbHiveLock l : locks) {
          if(l.txnId != hl.txnId) {
            //locks from different transactions detected (or from transaction and read-only query in autocommit)
            logMsg = true;
            break;
          }
          else if(l.txnId == 0) {
            if(!l.queryId.equals(hl.queryId)) {
              //here means no open transaction, but different queries
              logMsg = true;
              break;
            }
          }
        }
        if(logMsg) {
          LOG.warn("adding new DbHiveLock(" + hl + ") while we are already tracking locks: " + locks);
        }
      }
      locks.add(hl);
      if (res.getState() != LockState.ACQUIRED) {
        LOG.error("Unable to acquire locks for lockId={} after {} retries (retries took {} ms). QueryId={}\n{}",
                res.getLockid(), numRetries, retryDuration, queryId, res);
        if (res.getState() == LockState.WAITING) {
          /**
           * the {@link #unlock(HiveLock)} here is more about future proofing when support for
           * multi-statement txns is added.  In that case it's reasonable for the client
           * to retry this part of txn or try something else w/o aborting the whole txn.
           * Also for READ_COMMITTED (when and if that is supported).
           */
          unlock(hl);//remove the locks in Waiting state
          LockException le = new LockException(null, ErrorMsg.LOCK_ACQUIRE_TIMEDOUT,
            lock.toString(), Long.toString(retryDuration), res.toString());
          if(conf.getBoolVar(HiveConf.ConfVars.TXN_MGR_DUMP_LOCK_STATE_ON_ACQUIRE_TIMEOUT)) {
            showLocksNewFormat(le.getMessage());
          }
          throw le;
        }
        throw new LockException(ErrorMsg.LOCK_CANNOT_BE_ACQUIRED.getMsg() + " " + res);
      }
      acquiredLocks.add(hl);

      Metrics metrics = MetricsFactory.getInstance();
      if (metrics != null) {
        try {
          metrics.incrementCounter(MetricsConstant.METASTORE_HIVE_LOCKS);
        } catch (Exception e) {
          LOG.warn("Error Reporting hive client metastore lock operation to Metrics system", e);
        }
      }

      return res.getState();
    } catch (NoSuchTxnException e) {
      LOG.error("Metastore could not find " + JavaUtils.txnIdToString(lock.getTxnid()));
      throw new LockException(e, ErrorMsg.TXN_NO_SUCH_TRANSACTION, JavaUtils.txnIdToString(lock.getTxnid()));
    } catch (TxnAbortedException e) {
      LockException le = new LockException(e, ErrorMsg.TXN_ABORTED, JavaUtils.txnIdToString(lock.getTxnid()), e.getMessage());
      LOG.error(le.getMessage());
      throw le;
    } catch (TException e) {
      throw new LockException(ErrorMsg.METASTORE_COMMUNICATION_FAILED.getMsg(),
          e);
    }
  }
Send a lock request to the metastore.  This is intended for use by
{@link DbTxnManager}.
@param lock lock request
@param isBlocking if true, will block until locks have been acquired
@throws LockException
@return the result of the lock attempt
ql/src/java/org/apache/hadoop/hive/ql/lockmgr/DbLockManager.java