Esempio n. 1
0
  /** 判断两条记录是否可以作为一个batch提交,主要判断sql是否相等. 可优先通过schemaName进行判断 */
  private boolean canBatch(EventData source, EventData target) {
    // return StringUtils.equals(source.getSchemaName(), target.getSchemaName())
    // && StringUtils.equals(source.getTableName(), target.getTableName())
    // && StringUtils.equals(source.getSql(), target.getSql());
    // return StringUtils.equals(source.getSql(), target.getSql());

    // 因为sqlTemplate构造sql时用了String.intern()的操作,保证相同字符串的引用是同一个,所以可以直接使用==进行判断,提升效率
    return source.getSql() == target.getSql();
  }
Esempio n. 2
0
    // 大致估算一下row记录的大小
    private long calculateSize(EventData data) {
      // long size = 0L;
      // size += data.getKeys().toString().getBytes().length - 12 - data.getKeys().size() + 1L;
      // size += data.getColumns().toString().getBytes().length - 12 - data.getKeys().size() + 1L;
      // return size;

      // byte[] bytes = JsonUtils.marshalToByte(data);// 走序列化的方式快速计算一下大小
      // return bytes.length;

      return data.getSize(); // 数据不做计算,避免影响性能
    }
Esempio n. 3
0
    private void processStat(EventData data, int affect, boolean batch) {
      if (batch && (affect < 1 && affect != Statement.SUCCESS_NO_INFO)) {
        failedDatas.add(data); // 记录到错误的临时队列,进行重试处理
      } else if (!batch && affect < 1) {
        failedDatas.add(data); // 记录到错误的临时队列,进行重试处理
      } else {
        processedDatas.add(data); // 记录到成功的临时队列,commit也可能会失败。所以这记录也可能需要进行重试
        DbLoadCounter counter =
            context.getCounters().get(Arrays.asList(data.getSchemaName(), data.getTableName()));
        EventType type = data.getEventType();
        if (type.isInsert()) {
          counter.getInsertCount().incrementAndGet();
        } else if (type.isUpdate()) {
          counter.getUpdateCount().incrementAndGet();
        } else if (type.isDelete()) {
          counter.getDeleteCount().incrementAndGet();
        }

        counter.getRowSize().addAndGet(calculateSize(data));
      }
    }
Esempio n. 4
0
    private void doPreparedStatement(
        PreparedStatement ps, DbDialect dbDialect, LobCreator lobCreator, EventData data)
        throws SQLException {
      EventType type = data.getEventType();
      // 注意insert/update语句对应的字段数序都是将主键排在后面
      List<EventColumn> columns = new ArrayList<EventColumn>();
      if (type.isInsert()) {
        columns.addAll(data.getColumns()); // insert为所有字段
        columns.addAll(data.getKeys());
      } else if (type.isDelete()) {
        columns.addAll(data.getKeys());
      } else if (type.isUpdate()) {
        boolean existOldKeys = !CollectionUtils.isEmpty(data.getOldKeys());
        columns.addAll(data.getUpdatedColumns()); // 只更新带有isUpdate=true的字段
        columns.addAll(data.getKeys());
        if (existOldKeys) {
          columns.addAll(data.getOldKeys());
        }
      }
      for (int i = 0; i < columns.size(); i++) {
        int paramIndex = i + 1;
        EventColumn column = columns.get(i);
        int sqlType = column.getColumnType();

        // 获取一下当前字段名的数据是否必填
        Table table = dbDialect.findTable(data.getSchemaName(), data.getTableName());
        Map<String, Boolean> isRequiredMap = new HashMap<String, Boolean>();
        for (Column tableColumn : table.getColumns()) {
          isRequiredMap.put(StringUtils.lowerCase(tableColumn.getName()), tableColumn.isRequired());
        }

        Boolean isRequired = isRequiredMap.get(StringUtils.lowerCase(column.getColumnName()));
        if (isRequired == null) {
          throw new ClaveException(
              String.format(
                  "column name %s is not found in Table[%s]",
                  column.getColumnName(), table.toString()));
        }

        Object param =
            SqlUtils.stringToSqlValue(
                column.getColumnValue(), sqlType, isRequired, dbDialect.isEmptyStringNulled());
        try {
          switch (sqlType) {
            case Types.CLOB:
              lobCreator.setClobAsString(ps, paramIndex, (String) param);
              break;

            case Types.BLOB:
              lobCreator.setBlobAsBytes(ps, paramIndex, (byte[]) param);
              break;

            default:
              StatementCreatorUtils.setParameterValue(ps, paramIndex, sqlType, null, param);
              break;
          }
        } catch (SQLException ex) {
          logger.error(
              "## SetParam error , [table={}, sqltype={}, value={}]",
              new Object[] {data.getSchemaName() + "." + data.getTableName(), sqlType, param});
          throw ex;
        }
      }
    }