Spring Batch 的问题

Pra*_*mar 3 spring spring-batch spring-boot

嗨,我最近一直在 Spring Batch 工作,需要一些帮助。

1)我想使用多个线程运行我的作业,因此我使用了 TaskExecutor,如下所示,

            @Bean
            public TaskExecutor taskExecutor() {
                SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
                taskExecutor.setConcurrencyLimit(4);
                return taskExecutor;
            }

    @Bean
        public Step myStep() {
            return stepBuilderFactory.get("myStep")
                    .<MyEntity,AnotherEntity> chunk(1)
                    .reader(reader())
                    .processor(processor())
                    .writer(writer())
                    .taskExecutor(taskExecutor())
                    .throttleLimit(4)
                     .build();
        }
Run Code Online (Sandbox Code Playgroud)

但是,在执行时可以在控制台中看到下面的行。

osbclsupport.SimpleJobLauncher : 没有设置 TaskExecutor,默认为同步执行器。

这是什么意思?但是,在调试时,我可以看到四个 SimpleAsyncExecutor 线程正在运行。有人可以对此有所了解吗?

2)我不想使用 spring 批处理创建的元数据表运行我的批处理应用程序。我试过添加spring.batch.initialize-schema=never. 但它没有用。我还看到了一些通过使用ResourcelessTransactionManager,来做到这一点的方法MapJobRepositoryFactoryBean。但是我必须为我的工作进行一些数据库事务。那我用这个可以吗?我也能够通过扩展DefaultBatchConfigurer和覆盖来做到这一点:

@Override
    public void setDataSource(DataSource dataSource) {
        // override to do not set datasource even if a datasource exist.
        // initialize will use a Map based JobRepository (instead of database)
    }
Run Code Online (Sandbox Code Playgroud)

请进一步指导我。谢谢。

更新:

我的完整配置类在这里。

@EnableBatchProcessing
@EnableScheduling
@Configuration
public class MyBatchConfiguration{

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public DataSource dataSource;


    /* @Override
        public void setDataSource(DataSource dataSource) {
            // override to do not set datasource even if a datasource exist.
            // initialize will use a Map based JobRepository (instead of database)
        }*/
    @Bean
    public Step myStep() {

        return stepBuilderFactory.get("myStep")
                .<MyEntity,AnotherEntity> chunk(1)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .taskExecutor(executor())
                .throttleLimit(4)
                .build();
    }

    @Bean
    public Job myJob() {

        return jobBuilderFactory.get("myJob")
                .incrementer(new RunIdIncrementer())
                .listener(listener())
                .flow(myStep())
                .end()
                .build();
    }

    @Bean
    public MyJobListener myJobListener()
    {
        return new MyJobListener();
    }
    @Bean
    public ItemReader<MyEntity> reader()
    {

        return new MyReader();
    }

    @Bean
    public ItemWriter<? super AnotherEntity> writer()
    {
        return new MyWriter();
    }

    @Bean
    public ItemProcessor<MyEntity,AnotherEntity> processor()
    {
        return new MyProcessor();
    }

    @Bean
    public TaskExecutor taskExecutor() {
        SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
        taskExecutor.setConcurrencyLimit(4);
        return taskExecutor;
    }}
Run Code Online (Sandbox Code Playgroud)

Mic*_*lla 6

将来,请将其分解为两个独立的问题。话虽如此,让我对这两个问题进行一些说明。

SimpleJobLauncher :没有设置TaskExecutor,默认为同步执行器。

您的配置正在配置myStep为使用您的TaskExecutor. 它的作用是导致 Spring Batch 在它自己的线程中执行每个块(基于 的参数TaskExecutor)。您看到的日志消息与该行为无关。它与启动你的工作有关。默认情况下,SimpleJobLauncher将在其运行的同一线程上启动作业,从而阻塞该线程。您可以将 a 注入TaskExecutor到 中,SimpleJobLauncher这将导致作业在与JobLauncher自身不同的线程上执行。这是框架对多线程的两种不同使用。

我不想使用 spring 批处理创建的元数据表运行我的批处理应用程序

这里的简短回答是只对元数据表使用内存数据库,如 HSQLDB 或 H2。这提供了生产级数据存储(以便正确处理并发)而无需实际持久化数据。如果您使用ResourcelessTransactionManager,您实际上是在关闭事务(如果您正在以任何容量使用数据库,这是一个坏主意),因为这TransactionManager实际上并没有做任何事情(这是一个无操作实现)。