我在启动spring批处理应用程序时遇到了问题,我在这里提到过。现在我已经更新了使用hibernatetransactionmanager的代码,我的工作有6个步骤,第一步现在可以正常工作,但是第二步失败了。下面是我添加了hibernatetransactionmanager的更新代码。
batchscheduler.class类
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
//@Configuration
@EnableScheduling
public class BatchScheduler {
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
@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;
}
}
@Configuration
@EnableBatchProcessing
@Import({BatchScheduler.class})
public class LogBatchConfiguration {
private static final Logger log = LoggerFactory.getLogger(LogBatchConfiguration.class);
@Autowired private SimpleJobLauncher jobLauncher;
//**********New added
@Bean
public PlatformTransactionManager mytransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(createLocalSessionFactory(mainDataSource).getObject());
return transactionManager;
}
@Autowired
@Qualifier(value = "mainDataSource")
public DataSource mainDataSource;
@Autowired
@Qualifier(value = "toolsDataSource")
public DataSource toolsDataSource;
@Autowired public StepBuilderFactory stepBuilderFactory;
@Autowired public JobBuilderFactory jobBuilderFactory;
@Autowired private RestTemplate restTemplate;
@Qualifier(value = "createLocalSessionFactory")
@Autowired
private SessionFactory createLocalSessionFactory;
@Qualifier(value = "createToolSessionFactory")
@Autowired
private SessionFactory createToolSessionFactory;
@Bean
RestTemplate restTemplate(RestTemplateBuilder builder) {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonConverter =
(MappingJackson2HttpMessageConverter) converter;
jsonConverter.setObjectMapper(new ObjectMapper());
jsonConverter.setSupportedMediaTypes(
ImmutableList.of(
new MediaType(
"application", "json", MappingJackson2HttpMessageConverter.DEFAULT_CHARSET),
new MediaType(
"text", "javascript", MappingJackson2HttpMessageConverter.DEFAULT_CHARSET)));
}
}
return restTemplate;
}
@Bean
public LocalSessionFactoryBean createLocalSessionFactory(
@Qualifier("mainDataSource") DataSource dataSource) {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setPackagesToScan(
new String[] {
"com.abc.def..entities",
"com.abc.entities"
});
factory.setHibernateProperties(hibernateVCommitProperties());
return factory;
}
@Bean
public LocalSessionFactoryBean createToolSessionFactory(
@Qualifier("toolsDataSource") DataSource dataSource) {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setPackagesToScan(
new String[] {
"com.abc.def..entities",
"com.abc.entities"
});
factory.setHibernateProperties(hibernateCommitProperties());
return factory;
}
@Scheduled(cron = "${server.cron}")
public void SyncJobTrigger() throws Exception {
if (log.isInfoEnabled()) {
}
JobParameters param =
new JobParametersBuilder()
.addString("JobID", String.valueOf(System.currentTimeMillis()))
.toJobParameters();
JobExecution execution = jobLauncher.run(populateServerDataJob(), param);
if (log.isInfoEnabled()) {
log.info("BATCH tools Server job finished with status: " + execution.getStatus());
}
}
//--------------------------------- JOBS ----------------------------------------------
@Bean
public Job populateServerDataJob() throws Exception {
return jobBuilderFactory
.get("populateData")
.start(serverRequestData()) // this step's writer is failing
.next(a)
.build();
}
@Bean
@StepScope
public HibernateCursorItemReader<Request> myRequestReader() throws Exception {
// returns reader and works fine as seen in logs, data is fetched
}
@Bean
@StepScope
public requestToServerProcessor requestToServerRequestProcessor() {
return new requestToServerProcessor(mainDataSource);
}
// WRITER
@Bean
@StepScope
public HibernateItemWriter<ServerRequestDetails> serverRequestWriter() {
HibernateItemWriter<ServerRequestDetails> writer = new HibernateItemWriter();
writer.setSessionFactory(createLocalSessionFactory(mainDataSource).getObject());
return writer;
}
@Bean
@JobScope
public Step serverRequestData() throws Exception {
return stepBuilderFactory
.get("getServerRequestData")
.transactionManager(mytransactionManager())/*****added manager here.
.<Request, ServerRequestDetails>chunk(100)
.reader(mylRequestReader())
.processor(requestToServerRequestProcessor())
.writer(serverRequestWriter())
.build();
}
}
DataSourceConfiguration.class
@Configuration
public class DataSourceConfiguration {
private static final Logger log = LoggerFactory.getLogger(DataSourceConfiguration.class);
@Value("${spring.datasource.usern}")
private String insightsDbUser;
@Value("${spring.datasource.pass}")
private String insightsDbPass;
@Value("${spring.datasource.url}")
private String insightsDbConnection;
@Value("${tools.datasource.user}")
private String toolsDbUser
@Value("${tools.datasource.pass}")
private String toolsDbPass;
@Value("${tools.datasource.url}")
private String toolsDbConnection;
@Bean(name = "mainDataSource")
@Primary
public DataSource mainDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(insightsDbConnection);
dataSource.setUsername(insightsDbUser);
dataSource.setPassword(insightsDbPass);
if (log.isInfoEnabled()) {
//
}
return dataSource;
}
@Bean(name = "toolsDataSource")
public DataSource toolsDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(toolsDbConnection);
dataSource.setUsername(toolsDbUser);
dataSource.setPassword(toolsDbPass);
if (log.isInfoEnabled()) {
//
}
return dataSource;
}
}
现在在这个serverrequestdata中,是作业的第一步,步骤“a”是第二步,步骤“a”代码我没有放进去,因为它与步骤“serverrequestdata”完全相似。我创建了一个hibernatetransactionmanager,并在运行步骤时指定了它,但现在第一步可以正常工作。现在步骤“a”失败了,因为下面的错误与前面的失败类似,但我确实看到了额外的stacktrace:
2021-04-16 09:56:52.986 INFO 47235 --- [main] o.s.batch.core.job.SimpleStepHandler : Executing step: [a]
2021-04-16 09:56:59.305 INFO 47235 --- [main] o.s.batch.core.step.tasklet.TaskletStep : Commit failed while step execution data was already updated. Reverting to old version.
2021-04-16 09:56:59.308 ERROR 47235 --- [main] o.s.batch.core.step.AbstractStep : Encountered an error executing step getVsyncDetails in job populateVtoolsServerDataJob
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:413)
at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:3397)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1354)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1349)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:148)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:919)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:727)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:152)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy118.execute(Unknown Source)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:786)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.CoreApplication.main(CoreApplication.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
2021-04-16 09:56:59.309 INFO 47235 --- [main] o.s.batch.core.step.AbstractStep : Step: [a] executed in 6s323ms
2021-04-16 09:56:59.309 ERROR 47235 --- [main] o.s.batch.core.step.AbstractStep : Encountered an error saving batch meta data for step a in job populateServerDataJob. This job is now in an unknown state and should not be restarted.
org.springframework.dao.OptimisticLockingFailureException: Attempt to update step execution id=2 with wrong version (1), where current version is 2
at org.springframework.batch.core.repository.dao.MapStepExecutionDao.updateStepExecution(MapStepExecutionDao.java:106)
at org.springframework.batch.core.repository.support.SimpleJobRepository.update(SimpleJobRepository.java:196)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy93.update(Unknown Source)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:275)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy118.execute(Unknown Source)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155)
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:786)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.CoreApplication.main(CoreApplication.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
2021-04-16 09:56:59.313 INFO 47235 --- [main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=populateServerDataJob]] completed with the following parameters: [{}] and the following status: [UNKNOWN] in 9s178ms
我看到一个额外的日志
2021-04-16 09:56:59.305 INFO 47235 --- [main] o.s.batch.core.step.tasklet.TaskletStep : Commit failed while step execution data was already updated. Reverting to old version.
我以前没见过。
现在由于在添加hibernatetransactionmanager之后,第一步编写器工作正常,所以我在配置步骤a时添加了相同的事务管理。但现在我得到了同样的错误,但有一些额外的日志,所以我认为这背后可能有其他原因?
1条答案
按热度按时间np8igboo1#
你在宣布
ResourcelessTransactionManager
在spring批处理中默认使用的bean。由于此事务管理器不创建任何事务,因此hibernate项目编写器将失败并出现此错误。您需要配置spring批处理以使用
HibernateTransactionManager
(然后拆下ResourcelessTransactionManager
). 这可以使用本文文档中提到的自定义批处理配置器来完成。在你的例子中,可能是这样的: