private void updateStoreOnExec(RootProcedureState<TEnvironment> procStack,
    Procedure<TEnvironment> procedure, Procedure<TEnvironment>[] subprocs) {
    if (subprocs != null && !procedure.isFailed()) {
      if (LOG.isTraceEnabled()) {
        LOG.trace("Stored " + procedure + ", children " + Arrays.toString(subprocs));
      }
      store.insert(procedure, subprocs);
    } else {
      LOG.trace("Store update {}", procedure);
      if (procedure.isFinished() && !procedure.hasParent()) {
        // remove child procedures
        final long[] childProcIds = procStack.getSubprocedureIds();
        if (childProcIds != null) {
          store.delete(procedure, childProcIds);
          for (int i = 0; i < childProcIds.length; ++i) {
            procedures.remove(childProcIds[i]);
          }
        } else {
          store.update(procedure);
        }
      } else {
        store.update(procedure);
      }
    }
  }
Executes <code>procedure</code>
<ul>
<li>Calls the doExecute() of the procedure
<li>If the procedure execution didn't fail (i.e. valid user input)
<ul>
<li>...and returned subprocedures
<ul>
<li>The subprocedures are initialized.
<li>The subprocedures are added to the store
<li>The subprocedures are added to the runnable queue
<li>The procedure is now in a WAITING state, waiting for the subprocedures to complete
</ul>
</li>
<li>...if there are no subprocedure
<ul>
<li>the procedure completed successfully
<li>if there is a parent (WAITING)
<li>the parent state will be set to RUNNABLE
</ul>
</li>
</ul>
</li>
<li>In case of failure
<ul>
<li>The store is updated with the new state</li>
<li>The executor (caller of this method) will start the rollback of the procedure</li>
</ul>
</li>
</ul>
hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java