Esempio n. 1
0
 private EventColumn buildColumn(
     String name, int type, String value, boolean isKey, boolean isNull) {
   EventColumn column = new EventColumn();
   column.setColumnName(name);
   column.setColumnType(type);
   column.setColumnValue(value);
   column.setKey(isKey);
   column.setNull(isNull);
   return column;
 }
Esempio n. 2
0
 private EventColumn buildColumn(BatchProto.Column columnProto) {
   EventColumn column = new EventColumn();
   column.setColumnName(columnProto.getName());
   column.setNull(columnProto.getIsNull());
   column.setColumnType(columnProto.getType());
   column.setColumnValue(columnProto.getValue());
   column.setKey(columnProto.getIsPrimaryKey());
   column.setIndex(columnProto.getIndex());
   column.setUpdate(columnProto.getIsUpdate()); // add by ljh 2012-08-30,标记变更字段
   return column;
 }
Esempio n. 3
0
    public void run() {
      try {
        MDC.put(OtterConstants.splitPipelineLogFileKey, String.valueOf(pipeline.getId()));
        Thread.currentThread()
            .setName(String.format(WORKER_NAME_FORMAT, pipeline.getId(), pipeline.getName()));
        // 获取数据表信息
        DataMedia dataMedia = ConfigHelper.findDataMedia(pipeline, eventData.getTableId());
        DbDialect dbDialect =
            dbDialectFactory.getDbDialect(pipeline.getId(), (DbMediaSource) dataMedia.getSource());
        Table table = dbDialect.findTable(eventData.getSchemaName(), eventData.getTableName());
        TableData keyTableData = buildTableData(table, eventData.getKeys());

        // oracle类型特殊处理下
        if (dbDialect instanceof OracleDialect) {
          keyTableData.columnTypes = getOraclePkTypes(table, keyTableData.columnNames);
        }

        boolean needAll =
            pipeline.getParameters().getSyncMode().isRow()
                || (eventData.getSyncMode() != null && eventData.getSyncMode().isRow());

        // 增加一种case, 针对oracle erosa有时侯结果记录只有主键,没有变更字段,需要做一次反查,获取所有字段
        needAll |=
            CollectionUtils.isEmpty(eventData.getUpdatedColumns())
                && dataMedia.getSource().getType().isOracle();

        List<DataMediaPair> mediaParis =
            ConfigHelper.findDataMediaPairByMediaId(pipeline, dataMedia.getId());
        List<String> viewColumnNames =
            buildMaxColumnsFromColumnPairs(mediaParis, eventData.getKeys());

        // TODO 后续版本测试下
        // if (needAll) {
        // boolean needDb = checkNeedDbForRowMode(table,
        // viewColumnNames, eventData);
        // if (needAll && !needDb) {// 不需要进行反查
        // item.setFilter(false);
        // return;
        // }
        // }

        // modified by ljh at 2012-11-04
        // 反查数据时只反查带update=true标识的数据,因为update=false的记录可能只是进行filter需要用到的数据,不需要反查
        TableData columnTableData =
            buildTableData(table, eventData.getUpdatedColumns(), needAll, viewColumnNames);

        if (columnTableData.columnNames.length == 0) {
          // 全主键,不需要进行反查
        } else {
          List<String> newColumnValues =
              select(
                  dbDialect,
                  eventData.getSchemaName(),
                  eventData.getTableName(),
                  keyTableData,
                  columnTableData);

          if (newColumnValues == null) {
            // miss from db
            // 设置为filter=true,可能存在丢数据的风险.
            // 比如针对源库发生主备切换,otter反查的是备库,查询不到对应的记录
            // item.setFilter(true);

            // 针对需要自定义反查数据库的,允许忽略
            // a. 自由门触发的数据,不存在时可以忽略
            // b. 回环补救算法触发的数据,不存在时可以忽略
            boolean needFilter = eventData.isRemedy() || pipeline.getParameters().getSkipNoRow();
            item.setFilter(needFilter);

            // 判断主键是否有变更,如果变更了,就原样返回item
            int index = 0;
            for (EventColumn oldKey : eventData.getOldKeys()) {
              if (!oldKey.equals(eventData.getKeys().get(index))) {
                item.setFilter(false);
                break;
              }
            }
          } else {
            // 构造反查的返回结果
            List<EventColumn> newEventColumns = new ArrayList<EventColumn>();
            for (int i = 0; i < newColumnValues.size(); i++) {
              EventColumn column = new EventColumn();
              column.setIndex(columnTableData.indexs[i]);
              column.setColumnName(columnTableData.columnNames[i]);
              column.setColumnType(columnTableData.columnTypes[i]);
              column.setNull(newColumnValues.get(i) == null);
              column.setColumnValue(newColumnValues.get(i));
              column.setUpdate(true);
              newEventColumns.add(column);
            }

            // 处理下columns中不在反查字段内的字段列表
            for (EventColumn column : eventData.getColumns()) {
              boolean override = false;
              for (EventColumn newEventColumn : newEventColumns) {
                if (StringUtils.equalsIgnoreCase(
                    newEventColumn.getColumnName(), column.getColumnName())) {
                  override = true;
                  break;
                }
              }

              if (!override) { // 针对newcolumns不存在的记录进行添加
                newEventColumns.add(column);
              }
            }

            Collections.sort(newEventColumns, new EventColumnIndexComparable()); // 重新排个序
            eventData.setColumns(newEventColumns);
          }
        }
      } catch (InterruptedException e) {
        // ignore
      } finally {
        Thread.currentThread().setName(WORKER_NAME);
        MDC.remove(OtterConstants.splitPipelineLogFileKey);
      }
    }