Java 带有SimpleAsyncTaskExecutor的Spring批处理未保存到DB
我有一个简单的Spring引导应用程序,它有一个enpoint,通过JobLauncher bean中配置的SimpleAsynctaskeExecutor异步调用Spring批处理作业 Spring批处理作业异步启动,工作正常,但不会将任何内容保存到数据库中 如果删除SimpleAsyncTaskExecutor,则会保存数据Java 带有SimpleAsyncTaskExecutor的Spring批处理未保存到DB,java,spring-boot,spring-batch,Java,Spring Boot,Spring Batch,我有一个简单的Spring引导应用程序,它有一个enpoint,通过JobLauncher bean中配置的SimpleAsynctaskeExecutor异步调用Spring批处理作业 Spring批处理作业异步启动,工作正常,但不会将任何内容保存到数据库中 如果删除SimpleAsyncTaskExecutor,则会保存数据 @Component public class CustomBatchConfiguration implements BatchConfigurer { priva
@Component
public class CustomBatchConfiguration implements BatchConfigurer {
private static final Log LOGGER = LogFactory.getLog(CustomBatchConfiguration.class);
@Autowired
private BatchProperties properties;
@Autowired
private DataSource dataSource;
@Autowired
private EntityManagerFactory entityManagerFactory;
private PlatformTransactionManager transactionManager;
private JobRepository jobRepository;
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;
/**
* Registers {@link JobRepository} bean.
*/
@Override
public JobRepository getJobRepository() {
return this.jobRepository;
}
/**
* Registers {@link PlatformTransactionManager} bean.
*/
@Override
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
/**
* Registers {@link JobLauncher} bean.
*/
@Override
public JobLauncher getJobLauncher() {
return this.jobLauncher;
}
/**
* Registers {@link JobExplorer} bean. This bean is actually created in
* {@link BatchConfig}.
*/
@Override
public JobExplorer getJobExplorer() throws Exception {
return this.jobExplorer;
}
/**
* Initializes Spring Batch components.
*/
@PostConstruct
public void initialize() {
try {
this.transactionManager = createTransactionManager();
this.jobRepository = createJobRepository();
this.jobLauncher = createJobLauncher();
this.jobExplorer = createJobExplorer();
} catch (Exception ex) {
throw new IllegalStateException("Unable to initialize Spring Batch", ex);
}
}
private JobExplorer createJobExplorer() throws Exception {
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
jobExplorerFactoryBean.setDataSource(this.dataSource);
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
jobExplorerFactoryBean.setTablePrefix(tablePrefix);
}
jobExplorerFactoryBean.afterPropertiesSet();
return jobExplorerFactoryBean.getObject();
}
private JobLauncher createJobLauncher() throws Exception {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(getJobRepository());
simpleJobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor()); // (1)
simpleJobLauncher.afterPropertiesSet();
return simpleJobLauncher;
}
private JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDatabaseType("db2");
jobRepositoryFactoryBean.setDataSource(this.dataSource);
if (this.entityManagerFactory != null) {
LOGGER.warn("JPA does not support custom isolation levels, so locks may not be taken when launching Jobs");
jobRepositoryFactoryBean.setIsolationLevelForCreate("ISOLATION_DEFAULT");
}
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
jobRepositoryFactoryBean.setTablePrefix(tablePrefix);
}
jobRepositoryFactoryBean.setTransactionManager(getTransactionManager());
jobRepositoryFactoryBean.afterPropertiesSet();
return jobRepositoryFactoryBean.getObject();
}
private PlatformTransactionManager createTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
这是我的批处理配置程序。我用SimpleAsyncTaskExecutor配置JobLauncher。如果我删除行simplejoblancher.setTaskExecutor(新的SimpleAsyncTaskExecutor());//(1) 数据已保存
@Component
public class CustomBatchConfiguration implements BatchConfigurer {
private static final Log LOGGER = LogFactory.getLog(CustomBatchConfiguration.class);
@Autowired
private BatchProperties properties;
@Autowired
private DataSource dataSource;
@Autowired
private EntityManagerFactory entityManagerFactory;
private PlatformTransactionManager transactionManager;
private JobRepository jobRepository;
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;
/**
* Registers {@link JobRepository} bean.
*/
@Override
public JobRepository getJobRepository() {
return this.jobRepository;
}
/**
* Registers {@link PlatformTransactionManager} bean.
*/
@Override
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
/**
* Registers {@link JobLauncher} bean.
*/
@Override
public JobLauncher getJobLauncher() {
return this.jobLauncher;
}
/**
* Registers {@link JobExplorer} bean. This bean is actually created in
* {@link BatchConfig}.
*/
@Override
public JobExplorer getJobExplorer() throws Exception {
return this.jobExplorer;
}
/**
* Initializes Spring Batch components.
*/
@PostConstruct
public void initialize() {
try {
this.transactionManager = createTransactionManager();
this.jobRepository = createJobRepository();
this.jobLauncher = createJobLauncher();
this.jobExplorer = createJobExplorer();
} catch (Exception ex) {
throw new IllegalStateException("Unable to initialize Spring Batch", ex);
}
}
private JobExplorer createJobExplorer() throws Exception {
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
jobExplorerFactoryBean.setDataSource(this.dataSource);
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
jobExplorerFactoryBean.setTablePrefix(tablePrefix);
}
jobExplorerFactoryBean.afterPropertiesSet();
return jobExplorerFactoryBean.getObject();
}
private JobLauncher createJobLauncher() throws Exception {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(getJobRepository());
simpleJobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor()); // (1)
simpleJobLauncher.afterPropertiesSet();
return simpleJobLauncher;
}
private JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDatabaseType("db2");
jobRepositoryFactoryBean.setDataSource(this.dataSource);
if (this.entityManagerFactory != null) {
LOGGER.warn("JPA does not support custom isolation levels, so locks may not be taken when launching Jobs");
jobRepositoryFactoryBean.setIsolationLevelForCreate("ISOLATION_DEFAULT");
}
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
jobRepositoryFactoryBean.setTablePrefix(tablePrefix);
}
jobRepositoryFactoryBean.setTransactionManager(getTransactionManager());
jobRepositoryFactoryBean.afterPropertiesSet();
return jobRepositoryFactoryBean.getObject();
}
private PlatformTransactionManager createTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
这是我的批处理配置
@Autowired(required = true)
private MyItemReader myItemReader;
@Autowired(required = true)
private MyItemProcessor myItemProcessor;
@Autowired(required = true)
private MyItemWriter myItemWriter;
@Bean
public Step myStep(TaskExecutor taskExecutor) {
return stepBuilderFactory.get("myStepName")
.<SomeWrapper, SomeWrapper>chunk(
1)
.reader(myItemReader)
.processor(myItemProcessor).writer(myItemWriter)
.build();
}
@Bean(name = "myJob")
public Job myJob(Step myStep) {
return jobBuilderFactory.get("myJobName").incrementer(new RunIdIncrementer())
.flow(myStep).end().build();
}
@Autowired(必需=true)
私有MyItemReader MyItemReader;
@自动连线(必需=真)
私有MyItemProcessor MyItemProcessor;
@自动连线(必需=真)
私人MyItemWriter MyItemWriter;
@豆子
公共步骤myStep(TaskExecutor TaskExecutor){
返回stepBuilderFactory.get(“myStepName”)
.大块(
1)
.reader(myItemReader)
.processor(myItemProcessor).writer(myItemWriter)
.build();
}
@Bean(name=“myJob”)
公共作业myJob(步骤myStep){
返回jobBuilderFactory.get(“myJobName”).incrementer(新的RunIdIncrementer())
.flow(myStep.end().build();
}
我错过了什么
提前感谢我做了以下工作来解决我的问题:
CustomBatchConfiguration
中,我更改了以下内容
private PlatformTransactionManager createTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
simpleJobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
为了解决我的问题,我做了以下几点:
CustomBatchConfiguration
中,我更改了以下内容
private PlatformTransactionManager createTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
simpleJobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
谢谢!还请注意,可以在作业步骤级别指定事务管理器和任务执行器,例如
stepBuilders.get(“myStep”).listener(新的DefaultItemFailureHandler()).tasklet(myTasklet()).transactionManager(transactionManager).taskExecutor(taskExecutor).build()代码>非常感谢!还请注意,可以在作业步骤级别指定事务管理器和任务执行器,例如stepBuilders.get(“myStep”).listener(新的DefaultItemFailureHandler()).tasklet(myTasklet()).transactionManager(transactionManager).taskExecutor(taskExecutor).build()代码>