private static void processSequentially(ZKWatcher zkw, List<ZKUtilOp> ops)
    throws KeeperException, NoNodeException {
    for (ZKUtilOp op : ops) {
      if (op instanceof CreateAndFailSilent) {
        createAndFailSilent(zkw, (CreateAndFailSilent) op);
      } else if (op instanceof DeleteNodeFailSilent) {
        deleteNodeFailSilent(zkw, (DeleteNodeFailSilent) op);
      } else if (op instanceof SetData) {
        setData(zkw, (SetData) op);
      } else {
        throw new UnsupportedOperationException(
          "Unexpected ZKUtilOp type: " + op.getClass().getName());
      }
    }
  }
Use ZooKeeper's multi-update functionality. If all of the following are true: -
runSequentialOnMultiFailure is true - on calling multi, we get a ZooKeeper exception that can
be handled by a sequential call(*) Then: - we retry the operations one-by-one (sequentially)
Note *: an example is receiving a NodeExistsException from a "create" call. Without multi, a
user could call "createAndFailSilent" to ensure that a node exists if they don't care who
actually created the node (i.e. the NodeExistsException from ZooKeeper is caught). This will
cause all operations in the multi to fail, however, because the NodeExistsException that
zk.create throws will fail the multi transaction. In this case, if the previous conditions
hold, the commands are run sequentially, which should result in the correct final state, but
means that the operations will not run atomically.
@throws KeeperException if a ZooKeeper operation fails
hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java