Spring批处理注释分区程序问题
我正在尝试使用基于注释的方法和分区器创建一个spring批处理应用程序,这将由quartz scheduler触发,但会遇到以下问题Spring批处理注释分区程序问题,spring,spring-batch,Spring,Spring Batch,我正在尝试使用基于注释的方法和分区器创建一个spring批处理应用程序,这将由quartz scheduler触发,但会遇到以下问题 当作业被触发时,每个分区将按顺序而不是并行执行,即如果我有10个分区,而不是所有10个分区一起被触发/处理,那么它将逐个处理 当多个作业实例(根据我的要求需要)被触发时,它无法正确同步,即当第二个instance启动时,它使用第一个实例数据,第一个实例将停止处理,但将处于活动状态 以下是我的配置/类文件 BatchConfiguration.java- java(
public class MyPartitioner implements Partitioner
{
@Override
public Map<String, ExecutionContext> partition(int gridSize)
{
Map<String, ExecutionContext> partitionMap = new HashMap<String, ExecutionContext>();
List<String> partitionCodes = getPartitionCodes(sql);
int count = 1;
for (String partitionCode : partitionCodes)
{
ExecutionContext context = new ExecutionContext();
context.put("partitionCode", partitionCode);
context.put("name", "Thread" + count);
partitionMap.put(partitionCode, context);
count++;
}
return partitionMap;}}
公共类MyPartitioner实现了分区器
{
@凌驾
公共地图分区(int gridSize)
{
Map partitionMap=newhashmap();
List partitionCodes=getPartitionCodes(sql);
整数计数=1;
for(字符串分区代码:分区代码)
{
ExecutionContext=新的ExecutionContext();
context.put(“partitionCode”,partitionCode);
context.put(“名称”、“线程”+计数);
partitionMap.put(partitionCode,context);
计数++;
}
返回分区映射;}}
这个配置有问题吗?我将当前时间传递给作业的每个实例,以分别识别每个实例,但它仍然不起作用。对于问题1,我没有看到任何明显的错误。也就是说,我只是查看了一下,没有看到任何验证这一点的单元测试,所以它可能是构建器中的一个bug。需要进一步研究。对于问题2,我需要了解更多关于您的查询。您如何防止两个作业实例拾取相同的数据?感谢您的回复。我不明白你说的建筑商里的虫子是什么意思?对于问题2,我考虑更新那些在DB中拾取的记录,比如“picked For processing”,这样它就不会被另一个实例获取。这是正确的方法还是我可以使用其他方法?我的记录是根据数据库中的“partitionCode”列进行分组的。是的,process indicator模式是一种常见的批处理模式,作业将在其中标记要处理的记录,以便在重新启动时或其他作业实例不会拾取这些记录。通常,您将使用一个侦听器(步骤等)将它们标记为正在处理,然后使用另一个侦听器将它们标记为已处理。谢谢,但我仍然面临上述两个问题:(.由于找不到任何与基于注释的quartz+spring批处理相关的示例/文档,我如何将quartz scheduler与此应用程序集成?
public class QuartzJob implements org.quartz.Job
{
@Override
public void execute(org.quartz.JobExecutionContext jobExecutionContext) throws org.quartz.JobExecutionException
{
AnnotationConfigApplicationContext context;
try
{
context = new AnnotationConfigApplicationContext(BatchConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
org.springframework.batch.core.Job newJob = context.getBean("springBatch", org.springframework.batch.core.Job.class);
JobParameters param = new JobParametersBuilder().addLong("time",System.currentTimeMillis()).toJobParameters();
jobLauncher.run(newJob, param);
} catch (Exception e){}}}
public class MyQuartzListener implements ServletContextListener
{
private Scheduler scheduler;
@Override
public void contextDestroyed(ServletContextEvent arg0){ }
@Override
public void contextInitialized(ServletContextEvent ctx)
{
JobDetail job = JobBuilder.newJob(QuartzJob.class).withIdentity("SPRINGBATCH", "SPRINGBATCH").build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("SPRINGBATCH", "SPRINGBATCH").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(60).repeatForever()).build();
try
{
scheduler = ((StdSchedulerFactory) ctx.getServletContext().getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY)).getScheduler();
job.getJobDataMap().put("quartztime", System.currentTimeMillis());
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {} }
public class MyPartitioner implements Partitioner
{
@Override
public Map<String, ExecutionContext> partition(int gridSize)
{
Map<String, ExecutionContext> partitionMap = new HashMap<String, ExecutionContext>();
List<String> partitionCodes = getPartitionCodes(sql);
int count = 1;
for (String partitionCode : partitionCodes)
{
ExecutionContext context = new ExecutionContext();
context.put("partitionCode", partitionCode);
context.put("name", "Thread" + count);
partitionMap.put(partitionCode, context);
count++;
}
return partitionMap;}}