Spring 无限循环中的批处理作业 运行
Spring Batch Job Running in Infinite loop
我正在处理简单的 Spring 批处理作业。当我在无限循环中启动它的 运行ning 作业时。它不会停止。根据我的调度程序时间,它应该每 10 秒后 运行。但是当工作开始时它不会停止。它只是分别从 reader、处理器和写入器打印系统输出。我正在使用 reader、处理器和编写器创建作业。我正在通过注释进行所有配置。不是 xml。
这里是批量配置
@Configuration
@EnableBatchProcessing
@EnableScheduling
public class BatchJobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private SimpleJobLauncher jobLauncher;
@Scheduled(cron="*/10 * * * * *")
public void perform() throws Exception
{
Job job = job(step1());
JobParameters jobParameters = new JobParameters();
jobLauncher.run(job, jobParameters);
}
@Bean
public Step step1()
{
return stepBuilderFactory.get("step1").<Person, Person> chunk(1)
.reader(reader()).processor(processor()).writer(writer())
.build();
}
@Bean
public Job job(Step step1) throws Exception
{
return jobBuilderFactory.get("job")
.incrementer(new RunIdIncrementer()).flow(step1())
.end().build();
}
@Bean
public DataSource dataSource()
{
EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder();
return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
@Bean
public PersonReader reader() {
return new PersonReader();
}
@Bean
public PersonWriter writer() {
return new PersonWriter();
}
@Bean
public PersonProcessor processor() {
return new PersonProcessor();
}
@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager) throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
factory.afterPropertiesSet();
return factory;
}
@Bean
public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception {
return factory.getObject();
}
@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setJobRepository(jobRepository);
return launcher;
}
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
}
PersonReader.java
public class PersonReader implements ItemReader<Person> {
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
Person person = new Person();
System.out.println("In PersonReader");
return person;
}
}
PersonWriter.java
public class PersonWriter implements ItemWriter<Person> {
@Override
public void write(List<? extends Person> arg0) throws Exception {
System.out.println("IN PersonWriter");
}
}
PersonProcessor.java
public class PersonProcessor implements ItemProcessor<Person, Person> {
@Override
public Person process(Person arg0) throws Exception {
System.out.println("In PersonProcessor");
return arg0;
}
}
一步将 运行 直到您的 ItemReader
returns 无效。在你的情况下,你的 ItemReader
永远不会(它总是 returns 一个新的 Person
)所以它永远不会结束。
添加一个标志来抵抗reader到运行的无限循环
Reader:
public class PersonReader implements ItemReader<Person> {
private boolean batchJobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!batchJobState){
Person person = new Person();
System.out.println("In PersonReader");
batchJobState=true;
return person;
}
return null;
}
}
是否有人来到这里遇到同样的错误,但是使用 FlatFileItemReader
(什么是 Reader
实现),看看您是否有多个 step
和 同名.
我的 Spring 批处理项目有两个同名步骤。这两个执行中的最后一步导致死循环。
使用接口StepExecutionListener。
这将提供两种方法
在实例级别使用变量布尔值 FLAG。
public class PersonReader 实现 ItemReader,StepExecutionListener {
私人布尔值 jobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!**jobState**){
Person person = new Person();
System.out.println("In PersonReader");
jobState=true;
return person;
}
return null;
}
}
@Override
public void beforeStep(StepExecution stepExecution) { }
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
**jobState** = false;
return stepExecution.getExitStatus();
}
}
- 在 read() 方法执行之前 beforeStep 方法执行。
- read() 方法将标志设置为 true。
- read()方法执行后,afterStep方法将执行并设置flag为false。
- 每当您的调度程序在 10 分钟后开始作业时,该值最初将为 false。
我正在处理简单的 Spring 批处理作业。当我在无限循环中启动它的 运行ning 作业时。它不会停止。根据我的调度程序时间,它应该每 10 秒后 运行。但是当工作开始时它不会停止。它只是分别从 reader、处理器和写入器打印系统输出。我正在使用 reader、处理器和编写器创建作业。我正在通过注释进行所有配置。不是 xml。
这里是批量配置
@Configuration
@EnableBatchProcessing
@EnableScheduling
public class BatchJobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private SimpleJobLauncher jobLauncher;
@Scheduled(cron="*/10 * * * * *")
public void perform() throws Exception
{
Job job = job(step1());
JobParameters jobParameters = new JobParameters();
jobLauncher.run(job, jobParameters);
}
@Bean
public Step step1()
{
return stepBuilderFactory.get("step1").<Person, Person> chunk(1)
.reader(reader()).processor(processor()).writer(writer())
.build();
}
@Bean
public Job job(Step step1) throws Exception
{
return jobBuilderFactory.get("job")
.incrementer(new RunIdIncrementer()).flow(step1())
.end().build();
}
@Bean
public DataSource dataSource()
{
EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder();
return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
@Bean
public PersonReader reader() {
return new PersonReader();
}
@Bean
public PersonWriter writer() {
return new PersonWriter();
}
@Bean
public PersonProcessor processor() {
return new PersonProcessor();
}
@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager) throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
factory.afterPropertiesSet();
return factory;
}
@Bean
public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception {
return factory.getObject();
}
@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setJobRepository(jobRepository);
return launcher;
}
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
}
PersonReader.java
public class PersonReader implements ItemReader<Person> {
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
Person person = new Person();
System.out.println("In PersonReader");
return person;
}
}
PersonWriter.java
public class PersonWriter implements ItemWriter<Person> {
@Override
public void write(List<? extends Person> arg0) throws Exception {
System.out.println("IN PersonWriter");
}
}
PersonProcessor.java
public class PersonProcessor implements ItemProcessor<Person, Person> {
@Override
public Person process(Person arg0) throws Exception {
System.out.println("In PersonProcessor");
return arg0;
}
}
一步将 运行 直到您的 ItemReader
returns 无效。在你的情况下,你的 ItemReader
永远不会(它总是 returns 一个新的 Person
)所以它永远不会结束。
添加一个标志来抵抗reader到运行的无限循环
Reader:
public class PersonReader implements ItemReader<Person> {
private boolean batchJobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!batchJobState){
Person person = new Person();
System.out.println("In PersonReader");
batchJobState=true;
return person;
}
return null;
}
}
是否有人来到这里遇到同样的错误,但是使用 FlatFileItemReader
(什么是 Reader
实现),看看您是否有多个 step
和 同名.
我的 Spring 批处理项目有两个同名步骤。这两个执行中的最后一步导致死循环。
使用接口StepExecutionListener。 这将提供两种方法
在实例级别使用变量布尔值 FLAG。
public class PersonReader 实现 ItemReader,StepExecutionListener { 私人布尔值 jobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!**jobState**){
Person person = new Person();
System.out.println("In PersonReader");
jobState=true;
return person;
}
return null;
}
}
@Override public void beforeStep(StepExecution stepExecution) { }
@Override public ExitStatus afterStep(StepExecution stepExecution) {
**jobState** = false;
return stepExecution.getExitStatus();
}
}
- 在 read() 方法执行之前 beforeStep 方法执行。
- read() 方法将标志设置为 true。
- read()方法执行后,afterStep方法将执行并设置flag为false。
- 每当您的调度程序在 10 分钟后开始作业时,该值最初将为 false。