您好我最近一直在Spring批处理,需要一些帮助。
1)我想使用多个线程运行我的Job,因此我使用了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();
}
但是,执行时可以在控制台中查看以下行。
o.s.b.c.l.support.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)
}
请进一步指导我。感谢。
更新
我的完整配置类。
@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;
}}
答案 0 :(得分:1)
将来,请将其分解为两个独立的问题。话虽如此,让我对这两个问题有所了解。
SimpleJobLauncher:没有设置TaskExecutor,默认为同步执行程序。
您的配置正在配置myStep
以使用您的TaskExecutor
。这样做是因为它导致Spring Batch在其自己的线程中执行每个块(基于TaskExecutor
的参数)。您看到的日志消息与该行为无关。它与启动你的工作有关。默认情况下,SimpleJobLauncher
将在其运行的同一线程上启动作业,从而阻止该线程。您可以将TaskExecutor
注入SimpleJobLauncher
,这将导致作业在与JobLauncher
本身不同的线程上执行。这些是框架对多个线程的两个单独使用。
我不想使用春季批量创建的元数据表运行我的批处理应用程序
这里简短的回答是只使用内存数据库(如HSQLDB或H2)作为元数据表。这提供了生产级数据存储(以便正确处理并发),而不实际持久化数据。如果您使用ResourcelessTransactionManager
,则实际上是关闭了交易(如果您以任何身份使用数据库,这是一个糟糕的主意),因为TransactionManager
实际上并没有做任何事情(它和&#1}} #39; sa no-op implementation。)