如何知道Spring批次中哪个chunk失败并赋值给Counter值?
How to know which chunk has failed in Spring Batch and assign Counter value?
我在这里扩展这个问题 - Identify which chunk has failed in chunk based step in Spring Batch。
你能告诉我下面的代码吗?
- 如何知道哪个块失败了?
- 如何做一个计数器,给一个非PK的字段赋自增值并保存到DB?
在非容错步骤中,任何块中的第一个错误都会使该步骤失败,您可以在 ChunkListener
实现中使用计数器获取块编号,如前所述 previously。这是一个简单的例子:
import java.util.Arrays;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.JobLauncher;
import org.springframework.batch.core.listener.ChunkListenerSupport;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
.writer(items -> {
System.out.println("About to write items " + items);
if (items.contains(8)) {
throw new Exception("No 8 here!");
}
})
.listener(new MyChunkListener())
.build())
.build();
}
static class MyChunkListener extends ChunkListenerSupport {
private int counter;
@Override
public void beforeChunk(ChunkContext context) {
counter++;
}
@Override
public void afterChunkError(ChunkContext context) {
System.out.println("Chunk number " + counter + " failed");
}
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
这会打印:
About to write items [1, 2, 3, 4, 5]
About to write items [6, 7, 8, 9, 10]
Chunk number 2 failed
但是,在容错步骤中,将逐个重试项目,并且 Spring 批处理将创建单项目块。在这种情况下,将为每个单项块调用 ChunkListener
,因此应该正确解释计数器。这是前面示例的容错版本:
import java.util.Arrays;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.JobLauncher;
import org.springframework.batch.core.listener.ChunkListenerSupport;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.faultTolerant()
.skip(Exception.class)
.skipLimit(10)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
.writer(items -> {
System.out.println("About to write items " + items);
if (items.contains(8)) {
throw new Exception("No 8 here!");
}
})
.listener(new MyChunkListener())
.build())
.build();
}
static class MyChunkListener extends ChunkListenerSupport {
private int counter;
@Override
public void beforeChunk(ChunkContext context) {
counter++;
}
@Override
public void afterChunkError(ChunkContext context) {
System.out.println("Chunk number " + counter + " failed");
}
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
打印:
About to write items [1, 2, 3, 4, 5]
About to write items [6, 7, 8, 9, 10]
Chunk number 2 failed
About to write items [6]
About to write items [7]
About to write items [8]
Chunk number 5 failed
About to write items [9]
About to write items [10]
我在这里扩展这个问题 - Identify which chunk has failed in chunk based step in Spring Batch。
你能告诉我下面的代码吗?
- 如何知道哪个块失败了?
- 如何做一个计数器,给一个非PK的字段赋自增值并保存到DB?
在非容错步骤中,任何块中的第一个错误都会使该步骤失败,您可以在 ChunkListener
实现中使用计数器获取块编号,如前所述 previously。这是一个简单的例子:
import java.util.Arrays;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.JobLauncher;
import org.springframework.batch.core.listener.ChunkListenerSupport;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
.writer(items -> {
System.out.println("About to write items " + items);
if (items.contains(8)) {
throw new Exception("No 8 here!");
}
})
.listener(new MyChunkListener())
.build())
.build();
}
static class MyChunkListener extends ChunkListenerSupport {
private int counter;
@Override
public void beforeChunk(ChunkContext context) {
counter++;
}
@Override
public void afterChunkError(ChunkContext context) {
System.out.println("Chunk number " + counter + " failed");
}
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
这会打印:
About to write items [1, 2, 3, 4, 5]
About to write items [6, 7, 8, 9, 10]
Chunk number 2 failed
但是,在容错步骤中,将逐个重试项目,并且 Spring 批处理将创建单项目块。在这种情况下,将为每个单项块调用 ChunkListener
,因此应该正确解释计数器。这是前面示例的容错版本:
import java.util.Arrays;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.JobLauncher;
import org.springframework.batch.core.listener.ChunkListenerSupport;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.faultTolerant()
.skip(Exception.class)
.skipLimit(10)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
.writer(items -> {
System.out.println("About to write items " + items);
if (items.contains(8)) {
throw new Exception("No 8 here!");
}
})
.listener(new MyChunkListener())
.build())
.build();
}
static class MyChunkListener extends ChunkListenerSupport {
private int counter;
@Override
public void beforeChunk(ChunkContext context) {
counter++;
}
@Override
public void afterChunkError(ChunkContext context) {
System.out.println("Chunk number " + counter + " failed");
}
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
打印:
About to write items [1, 2, 3, 4, 5]
About to write items [6, 7, 8, 9, 10]
Chunk number 2 failed
About to write items [6]
About to write items [7]
About to write items [8]
Chunk number 5 failed
About to write items [9]
About to write items [10]