final void restoreLock(TEnvironment env) {
    if (!lockedWhenLoading) {
      LOG.debug("{} didn't hold the lock before restarting, skip acquiring lock.", this);
      return;
    }

    if (isFinished()) {
      LOG.debug("{} is already finished, skip acquiring lock.", this);
      return;
    }

    if (isBypass()) {
      LOG.debug("{} is already bypassed, skip acquiring lock.", this);
      return;
    }
    // this can happen if the parent stores the sub procedures but before it can
    // release its lock, the master restarts
    if (getState() == ProcedureState.WAITING && !holdLock(env)) {
      LOG.debug("{} is in WAITING STATE, and holdLock=false, skip acquiring lock.", this);
      lockedWhenLoading = false;
      return;
    }
    LOG.debug("{} held the lock before restarting, call acquireLock to restore it.", this);
    LockState state = acquireLock(env);
    assert state == LockState.LOCK_ACQUIRED;
  }
Internal method called by the ProcedureExecutor that starts the user-level code rollback().
hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java