MultiResourcePartitioner - 加载相同资源的多个分区

时间:2017-03-19 12:53:05

标签: spring spring-batch batch-processing

我在spring批处理中使用本地分区将xml文件写入数据库。我已经将原始文件拆分为较小的文件,并且我已经使用MultiResourcePartitioner处理它们中的每一个,因为每个文件将由一个线程处理。我正在违反主键约束错误我不知道如何处理这个问题

文件列表

enter image description here

分区程序

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

使用XML文件作为读者输入的StaxEventItemReader

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

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您的阅读器有这一行,这会导致所有分区加载相同的文件:

reader.setResource(new ClassPathResource("data/customerOutput1-25000.xml"));

它应该从步骤执行上下文中获取资源。您可以使用open()接口或ItemStream接口的beforeStep()方法在StepExectionListener方法中访问执行上下文。这里有点个人偏好,但我一般使用ItemStream的事情是&#34;更好&#34;溶液