MultiResourcePartitioner - 多个分区加载相同的资源
MultiResourcePartitioner - Multiple Partitions Loading Same Resource
我在 spring 批处理中使用本地分区将 xml 文件写入数据库。我已经将原始文件拆分为较小的文件,并且我已经使用 MultiResourcePartitioner 来处理每个文件,因为每个文件将由一个线程处理。我收到 违反主键约束 错误我不知道如何处理这个问题
文件列表
分区器
@Bean
public Partitioner partitioner1(){
MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
Resource[] resources;
try {
resources = resourcePatternResolver.getResources("file:src/main/resources/data/*.xml");
} catch (IOException e) {
throw new RuntimeException("I/O problems when resolving the input file pattern.",e);
}
partitioner.setResources(resources);
return partitioner;
}
StaxEventItemReader 使用 XML 文件作为 reader
的输入
@Bean
@StepScope
public StaxEventItemReader<Customer> CustomerItemReader() {
XStreamMarshaller unmarshaller = new XStreamMarshaller();
Map<String, Class> aliases = new HashMap<>();
aliases.put("customer", Customer.class);
unmarshaller.setAliases(aliases);
StaxEventItemReader<Customer> reader = new StaxEventItemReader<>();
reader.setResource(new ClassPathResource("data/customerOutput1-25000.xml"));
reader.setFragmentRootElementName("customer");
reader.setUnmarshaller(unmarshaller);
return reader;
}
JdbcBatchItemWriter(写入数据库)
@Bean
@StepScope
public JdbcBatchItemWriter<Customer> customerItemWriter() {
JdbcBatchItemWriter<Customer> itemWriter = new JdbcBatchItemWriter<>();
itemWriter.setDataSource(this.dataSource);
itemWriter.setSql("INSERT INTO NEW_CUSTOMER VALUES (:id, :firstName, :lastName, :birthdate)");
itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
itemWriter.afterPropertiesSet();
return itemWriter;
}
感谢您的帮助
您的 reader 有这一行,这会导致所有分区加载同一个文件:
reader.setResource(new ClassPathResource("data/customerOutput1-25000.xml"));
它应该改为从步骤执行上下文中获取资源。您可以使用 ItemStream
接口的 open()
方法或 StepExectionListener
接口的 beforeStep()
方法访问执行上下文。这里有点个人偏好,但我通常使用 ItemStream
是 "better" 解决方案。
我在 spring 批处理中使用本地分区将 xml 文件写入数据库。我已经将原始文件拆分为较小的文件,并且我已经使用 MultiResourcePartitioner 来处理每个文件,因为每个文件将由一个线程处理。我收到 违反主键约束 错误我不知道如何处理这个问题
文件列表
分区器
@Bean
public Partitioner partitioner1(){
MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
Resource[] resources;
try {
resources = resourcePatternResolver.getResources("file:src/main/resources/data/*.xml");
} catch (IOException e) {
throw new RuntimeException("I/O problems when resolving the input file pattern.",e);
}
partitioner.setResources(resources);
return partitioner;
}
StaxEventItemReader 使用 XML 文件作为 reader
的输入 @Bean
@StepScope
public StaxEventItemReader<Customer> CustomerItemReader() {
XStreamMarshaller unmarshaller = new XStreamMarshaller();
Map<String, Class> aliases = new HashMap<>();
aliases.put("customer", Customer.class);
unmarshaller.setAliases(aliases);
StaxEventItemReader<Customer> reader = new StaxEventItemReader<>();
reader.setResource(new ClassPathResource("data/customerOutput1-25000.xml"));
reader.setFragmentRootElementName("customer");
reader.setUnmarshaller(unmarshaller);
return reader;
}
JdbcBatchItemWriter(写入数据库)
@Bean
@StepScope
public JdbcBatchItemWriter<Customer> customerItemWriter() {
JdbcBatchItemWriter<Customer> itemWriter = new JdbcBatchItemWriter<>();
itemWriter.setDataSource(this.dataSource);
itemWriter.setSql("INSERT INTO NEW_CUSTOMER VALUES (:id, :firstName, :lastName, :birthdate)");
itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
itemWriter.afterPropertiesSet();
return itemWriter;
}
感谢您的帮助
您的 reader 有这一行,这会导致所有分区加载同一个文件:
reader.setResource(new ClassPathResource("data/customerOutput1-25000.xml"));
它应该改为从步骤执行上下文中获取资源。您可以使用 ItemStream
接口的 open()
方法或 StepExectionListener
接口的 beforeStep()
方法访问执行上下文。这里有点个人偏好,但我通常使用 ItemStream
是 "better" 解决方案。