我们有一个场景,每当作业执行 STARTED 状态时,服务器可能会崩溃。在这种情况下,要重新启动批处理,我从这里理解Spring Batch在服务器故障后恢复,需要将batch_job_execution和batch_step_execution中的status和end_time列值从STARTED更新为FAILED,JobOperator.restart(jobExecutionId) API才能工作。
但是调用它会给出“NoSuchJobException:没有注册名称为 [] 的作业配置”,因为 JobOperator 内的 jobRegistry 映射是空的。
现在如何在服务器重新启动时使用这些作业信息重新填充 JobRegistry,以便我们可以调用 JobOperator.restart(jobExecutionId)。
下面是我的代码
/** The Test properties. */
@Autowired
private TestProperties TestProperties;
@Primary
@Bean(name = "TestDataSource")
public DataSource batchDataSource() {
DataSource TestDBSrc = DataSourceBuilder.create().username(getUsername()).password(getPassword()).url(getUrl()).build();
if (TestDBSrc != null && TestDBSrc instanceof HikariDataSource) {
@SuppressWarnings("resource")
HikariDataSource hikariDatsource = (HikariDataSource) TestDBSrc;
hikariDatsource.setSchema(getSchema());
}
return TestDBSrc;
}
private String getSchema() {
return TestProperties.getValue("spring.datasource.hikari.schema", "");
}
private String getUsername() {
return TestProperties.getValue("spring.datasource.username", "");
}
private String getPassword() {
return TestProperties.getValue("spring.datasource.password", "");
}
private String getUrl() {
return TestProperties.getValue("spring.datasource.jdbc-url", "");
}
@Bean(name = "transactionManager")
public JdbcTransactionManager batchTransactionManager(@Qualifier("TestDataSource") DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
@Bean(name = "TestBatchJobRepository")
public JobRepository jobRepository(@Qualifier("TestDataSource") DataSource batchDataSource,
@Qualifier("transactionManager") JdbcTransactionManager batchTransactionManager) throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(batchDataSource);
factory.setTransactionManager(batchTransactionManager);
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean(name = "TestBatchJobLauncher")
public JobLauncher jobLauncher(@Qualifier("TestBatchJobRepository") JobRepository jobRepository) throws Exception {
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
@Bean (name = "TestBatchJobExplorer")
public JobExplorer jobExplorer(@Qualifier("TestDataSource") DataSource dataSource,@Qualifier("transactionManager")JdbcTransactionManager batchTransactionManager) throws Exception {
final JobExplorerFactoryBean bean = new JobExplorerFactoryBean();
bean.setDataSource(dataSource);
bean.setTransactionManager(batchTransactionManager);
bean.setTablePrefix("BATCH_");
bean.setJdbcOperations(new JdbcTemplate(dataSource));
bean.afterPropertiesSet();
return bean.getObject();
}
@Bean (name ="TestBatchJobRegistry")
public JobRegistry jobRegistry() throws Exception {
return new MapJobRegistry();
}
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(@Qualifier("TestBatchJobRegistry") JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
postProcessor.setJobRegistry(jobRegistry);
return postProcessor;
}
@Bean (name = "TestBatchJobOperator")
public JobOperator jobOperator(@Qualifier("TestBatchJobLauncher") JobLauncher jobLauncher, @Qualifier("TestBatchJobRepository") JobRepository jobRepository,
@Qualifier("TestBatchJobRegistry") JobRegistry jobRegistry, @Qualifier("TestBatchJobExplorer") JobExplorer jobExplorer) {
final SimpleJobOperator jobOperator = new SimpleJobOperator();
jobOperator.setJobLauncher(jobLauncher);
jobOperator.setJobRepository(jobRepository);
jobOperator.setJobRegistry(jobRegistry);
jobOperator.setJobExplorer(jobExplorer);
return jobOperator;
}
}
这里因为我使用的是默认的内存映射
@Bean (name ="TestBatchJobRegistry")
public JobRegistry jobRegistry() throws Exception {
return new MapJobRegistry();
}
服务器重启后它会被清除。
情况不应该是这样,因为您已经注册了
JobRegistryBeanPostProcessor
。这是 bean 后处理器,每次(重新)启动 Spring 应用程序上下文时都会填充作业注册表。