protected void maybeReleaseTvList(TVList tvList) {
    long startTimeInMs = System.currentTimeMillis();
    boolean succeed = false;
    while (!succeed) {
      try {
        tryReleaseTvList(tvList);
        succeed = true;
      } catch (MemoryNotEnoughException ex) {
        long waitQueryInMs = System.currentTimeMillis() - startTimeInMs;
        if (waitQueryInMs > MAX_WAIT_QUERY_MS) {
          // Abort first query in the list. When all queries in the list have been aborted,
          // tryReleaseTvList will ensure succeed finally.
          tvList.lockQueryList();
          try {
            // fail the first query
            Iterator<QueryContext> iterator = tvList.getQueryContextSet().iterator();
            if (iterator.hasNext()) {
              FragmentInstanceContext firstQuery = (FragmentInstanceContext) iterator.next();
              firstQuery.failed(
                  new MemoryNotEnoughException(
                      "Memory not enough to clone the tvlist during flush phase"));
            }
          } finally {
            tvList.unlockQueryList();
          }
        }

        // sleep 100ms to retry
        try {
          Thread.sleep(RETRY_INTERVAL_MS);
        } catch (InterruptedException ignore) {
          Thread.currentThread().interrupt();
        }
      }
    }
  }
Release the TVList if there is no query on it. Otherwise, it should set the first query as the
owner. TVList is released until all queries finish. If it throws memory-not-enough exception
during owner transfer, retry the release process after 100ms. If the problem is still not
solved in 60s, it starts to abort first query, kick it out of the query list and retry. This
method must ensure success because it's part of flushing.

@param tvList
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java