@Override
  public synchronized void close() throws SQLException {
    try {
      closeLock.writeLock().lock();
      if (closed) {
        return;
      }
      closed = true;
    } finally {
      closeLock.writeLock().unlock();
    }

    try {
      Collection<ConnectionQueryServices> connectionQueryServices =
          connectionQueryServicesMap.values();
      try {
        SQLCloseables.closeAll(connectionQueryServices);
      } finally {
        connectionQueryServices.clear();
      }
    } finally {
      if (services != null) {
        try {
          services.close();
        } finally {
          ExecutorService executor = services.getExecutor();
          // Even if something wrong happened while closing services above, we still
          // want to set it to null. Otherwise, we will end up having a possibly non-working
          // services instance.
          services = null;
          executor.shutdown();
        }
      }
    }
  }
 @Override
 public void close() throws SQLException {
   try {
     SQLCloseables.closeAll(connectionQueryServicesMap.values());
   } finally {
     connectionQueryServicesMap.clear();
   }
 }