public static void deleteChildrenRecursivelyMultiOrSequential(ZKWatcher zkw,
    boolean runSequentialOnMultiFailure, String... pathRoots) throws KeeperException {
    if (pathRoots == null || pathRoots.length <= 0) {
      LOG.warn("Given path is not valid!");
      return;
    }
    List<ZKUtilOp> ops = new ArrayList<>();
    for (String eachRoot : pathRoots) {
      List<String> children = listChildrenBFSNoWatch(zkw, eachRoot);
      // Delete the leaves first and eventually get rid of the root
      for (int i = children.size() - 1; i >= 0; --i) {
        ops.add(ZKUtilOp.deleteNodeFailSilent(children.get(i)));
      }
    }
    submitBatchedMultiOrSequential(zkw, runSequentialOnMultiFailure, ops);
  }
Delete all the children of the specified node but not the node itself. This will first traverse
the znode tree for listing the children and then delete these znodes using multi-update api or
sequential based on the specified configurations.
<p>
Sets no watches. Throws all exceptions besides dealing with deletion of children.
<p>
If the following is true:
<ul>
<li>runSequentialOnMultiFailure is true
</ul>
on calling multi, we get a ZooKeeper exception that can be handled by a sequential call(*), we
retry the operations one-by-one (sequentially). - zk reference - if true when we get a
ZooKeeper exception that could retry the operations one-by-one (sequentially) - path of the
parent node(s)
@throws KeeperException.NotEmptyException if node has children while deleting if unexpected
                                          ZooKeeper exception if an invalid path is specified
hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java