Spring Batch:多线程场景下如何获取FlatFileItemReader读取的TSV文件行号
问题根源
默认FlatFileItemReader的行号存储在实例的currentRecordCount属性中,属于非线程安全的共享变量,多线程并发读取时多个线程会同时修改该值,导致行号计数错乱。且原生FlatFileItemReader本身不支持多线程场景下的可靠读取,直接搭配多线程taskExecutor使用本身就存在数据读取异常的风险。
可行解决方案
下面按适用场景从优到劣给出可落地的解决方式:
- 方案一:单线程读取 + 多线程处理拆分架构
关闭读步骤的多线程配置,改用单线程执行TSV文件读取,读取时直接将行号绑定到对应业务实体上,再将绑定好行号的实体提交到多线程处理逻辑中执行后续业务操作。该方案能100%保证行号准确性,同时保留多线程处理的性能优势,是最推荐的落地方式。 - 方案二:改用分区步实现并行读取
若TSV文件体积较大需要并行读取,优先使用Spring Batch的分区步(Partition Step)替代普通多线程步。自定义分区逻辑将源文件拆分为多个互不重叠的字节分区,每个分区分配给独立的子线程处理,每个子线程持有专属的FlatFileItemReader实例,各自维护分区内的行号,再结合分区的起始偏移量计算得到该行在全局源文件中的真实行号。 - 方案三:自定义线程安全的LineMapper实现
若必须在普通多线程步中直接完成读取+处理逻辑,可以自定义带原子行号计数的LineMapper实现,在读行阶段就通过原子类计算全局行号并绑定到实体,避免共享变量冲突。该方案仅适合小文件场景,大文件下并发读取会出现行序错乱问题。
代码示例(方案三实现)
// 自定义带行号绑定的LineMapper public class LineNumberBindLineMapper<T> implements LineMapper<T> { // 原生LineMapper委托,处理实际的行转实体逻辑 private final LineMapper<T> delegate; // 原子计数器保证全局行号唯一 private final AtomicInteger globalLineCounter = new AtomicInteger(0); @Override public T mapLine(String line, int lineNumber) throws Exception { // 原子自增获取全局真实行号,覆盖原生非线程安全的lineNumber参数 int realLineNum = globalLineCounter.incrementAndGet(); T entity = delegate.mapLine(line, realLineNum); // 若业务实体继承了公共的行号属性父类,直接统一赋值 if (entity instanceof TsvBaseEntity) { ((TsvBaseEntity) entity).setSourceFileLineNum(realLineNum); } return entity; } // 构造方法传入原生的LineMapper实现,比如默认的DelimitedLineMapper public LineNumberBindLineMapper(LineMapper<T> delegate) { this.delegate = delegate; } } // reader配置示例 @Bean public FlatFileItemReader<TsvDataEntity> tsvReader() { FlatFileItemReader<TsvDataEntity> reader = new FlatFileItemReader<>(); reader.setResource(new FileSystemResource("path/to/your/file.tsv")); reader.setLinesToSkip(1); // 跳过表头的话配置对应行数 // 使用自定义的LineMapper替换原生实现 reader.setLineMapper(new LineNumberBindLineMapper<>(yourOriginLineMapper())); return reader; }
注意事项
- 不要直接调用原生
FlatFileItemReader的getCurrentItemCount()方法在多线程场景下获取行号,该方法无并发控制,返回值不可靠。 - 若需要严格保证行号和文件内的行顺序完全一致,必须使用单线程读取逻辑,并行读取场景下无法完全保证行处理顺序和源文件顺序一致。
内容的提问来源于stack exchange,提问作者Shivangi Shukla
相关产品推荐
相关产品推荐

