public Stat setData(String path, byte[] data, int version)
    throws KeeperException, InterruptedException {
    final Span span = TraceUtil.createSpan("RecoverableZookeeper.setData");
    try (Scope ignored = span.makeCurrent()) {
      RetryCounter retryCounter = retryCounterFactory.create();
      byte[] newData = ZKMetadata.appendMetaData(id, data);
      boolean isRetry = false;
      while (true) {
        try {
          span.setStatus(StatusCode.OK);
          return checkZk().setData(path, newData, version);
        } catch (KeeperException e) {
          switch (e.code()) {
            case CONNECTIONLOSS:
            case OPERATIONTIMEOUT:
            case REQUESTTIMEOUT:
              TraceUtil.setError(span, e);
              retryOrThrow(retryCounter, e, "setData");
              break;
            case BADVERSION:
              if (isRetry) {
                // try to verify whether the previous setData success or not
                try {
                  Stat stat = new Stat();
                  byte[] revData = checkZk().getData(path, false, stat);
                  if (Bytes.compareTo(revData, newData) == 0) {
                    // the bad version is caused by previous successful setData
                    return stat;
                  }
                } catch (KeeperException keeperException) {
                  // the ZK is not reliable at this moment. just throwing exception
                  TraceUtil.setError(span, e);
                  throw keeperException;
                }
              }
              // throw other exceptions and verified bad version exceptions
            default:
              TraceUtil.setError(span, e);
              throw e;
          }
        }
        retryCounter.sleepUntilNextRetry();
        isRetry = true;
      }
    } finally {
      span.end();
    }
  }
setData is NOT an idempotent operation. Retry may cause BadVersion Exception Adding an
identifier field into the data to check whether badversion is caused by the result of previous
correctly setData
@return Stat instance
hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java