在春季批处理(spring-boot-1.5.2.RELEASE)中使用多个数据源在启动时引发异常

Posted

技术标签:

【中文标题】在春季批处理(spring-boot-1.5.2.RELEASE)中使用多个数据源在启动时引发异常【英文标题】:Using multiple datasources in springbatch (spring-boot-1.5.2.RELEASE) throwing exception on bootup 【发布时间】:2017-12-29 00:01:33 【问题描述】:

我正在尝试使用两个数据源,一个用于 Spring Batch 中的元数据表,另一个用于读取/处理/写入我的应用程序数据库。当我尝试同时使用这两种方法时,会出现以下异常。

    java.lang.IllegalStateException: To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2
    at org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.getConfigurer(AbstractBatchConfiguration.java:108) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.initialize(SimpleBatchConfiguration.java:114) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$ReferenceTargetSource.createObject(SimpleBatchConfiguration.java:142) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.aop.target.AbstractLazyCreationTargetSource.getTarget(AbstractLazyCreationTargetSource.java:86) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at com.sun.proxy.$Proxy43.getJobInstances(Unknown Source)


----------

    import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;

import com.springbatch_sample.domain.Person;

@Configuration
@EnableBatchProcessing
public class BatchConfiguration 

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;



    @Bean
    @Primary
    public DataSource hsqldbDataSource() throws SQLException 
        final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriver(new org.hsqldb.jdbcDriver());
        dataSource.setUrl("jdbc:hsqldb:hsql://localhost:9001/xdb");
        dataSource.setUsername("sa");
        dataSource.setPassword("sa");
        return dataSource;
    

    @Bean
    public JdbcTemplate jdbcTemplate(final DataSource dataSource) 
        return new JdbcTemplate(dataSource);
    

    @Bean
    @Qualifier("mysqlDataSource")
    public DataSource mysqlDataSource() throws SQLException 
        final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriver(new com.ibm.db2.jcc.DB2Driver());
        dataSource.setUrl("jdbc:db2://xxxx");
        dataSource.setUsername("user");
        dataSource.setPassword("pswd");
        //DatabasePopulatorUtils.execute(databasePopulator(), dataSource);
        return dataSource;
    

    @Bean
    public FlatFileItemReader<Person> reader() 
        FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
        reader.setResource(new ClassPathResource("sample-data.csv"));
        reader.setLineMapper(new DefaultLineMapper<Person>() 
            setLineTokenizer(new DelimitedLineTokenizer() 
                setNames(new String[]  "firstName", "lastName" );
            );
            setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() 
                setTargetType(Person.class);
            );
        );
        return reader;
    

    @Bean
    public PersonItemProcessor processor() 
        return new PersonItemProcessor();
    

    @Bean
    public JdbcBatchItemWriter<Person> writer() throws SQLException 
        JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
        writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
        writer.setDataSource(hsqldbDataSource());
        return writer;
    
    // end::readerwriterprocessor[]

    // tag::jobstep[]
    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener) throws SQLException 
        return jobBuilderFactory.get("importUserJob")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .flow(step1())
                .end()
                .build();
    

    @Bean
    public Step step1() throws SQLException 
        return stepBuilderFactory.get("step1")
                .<Person, Person> chunk(10)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    
    // end::jobstep[]

【问题讨论】:

请添加堆栈跟踪。我看到你正在使用 HSQL DB 的作业元数据和 itemWriter? Use of multiple DataSources in Spring Batch的可能重复 【参考方案1】:

Use of multiple DataSources in Spring Batch

查看此链接。 同样的问题,我通过那个链接解决了我的问题。

【讨论】:

以上是关于在春季批处理(spring-boot-1.5.2.RELEASE)中使用多个数据源在启动时引发异常的主要内容,如果未能解决你的问题,请参考以下文章

IndexOutOfBoundsException 春季批处理和春季启动

如何在春季批处理中使用sftp上传多个文件

春季批处理作业未读取第一行

事务未在春季批处理项目编写器中回滚

在春季批处理部署程序分区处理程序中定期获取正在运行的工作节点的状态

春季批处理继续运行