@Override
  public void execute(RouteResultset rrs, int type) {
    if (LOGGER.isDebugEnabled()) {
      StringBuilder s = new StringBuilder();
      LOGGER.debug(s.append(source).append(rrs).toString());
    }

    // 检查路由结果是否为空
    RouteResultsetNode[] nodes = rrs.getNodes();
    if (nodes == null || nodes.length == 0) {
      source.writeErrMessage(ErrorCode.ER_NO_DB_ERROR, "No dataNode selected");
      return;
    }

    // 选择执行方式
    if (nodes.length == 1) {
      singleNodeExecutor.execute(nodes[0], this, rrs.getFlag());
    } else {
      // 多数据节点,非事务模式下,执行的是可修改数据的SQL,则后端为事务模式。
      boolean autocommit = source.isAutocommit();
      if (autocommit && isModifySQL(type)) {
        autocommit = false;
      }
      //   multiNodeExecutor.execute(nodes, autocommit, this, rrs.getFlag());
    }
  }
 @Override
 public void commit() {
   final int initCount = target.size();
   if (initCount <= 0) {
     ByteBuffer buffer = source.allocate();
     buffer = source.writeToBuffer(OkPacket.OK, buffer);
     source.write(buffer);
     return;
   }
   commitExecutor.commit(null, this, initCount);
 }
 @Override
 public void cancel(FrontendConnection sponsor) {
   // TODO terminate session
   source.writeErrMessage(ErrorCode.ER_QUERY_INTERRUPTED, "Query execution was interrupted");
   if (sponsor != null) {
     OkPacket packet = new OkPacket();
     packet.packetId = 1;
     packet.affectedRows = 0;
     packet.serverStatus = 2;
     packet.write(sponsor);
   }
 }