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; }
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; }
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); } }