提交失败,步骤执行数据已更新恢复到旧版本Spring批

bvuwiixz  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(326)

我在启动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时添加了相同的事务管理。但现在我得到了同样的错误,但有一些额外的日志,所以我认为这背后可能有其他原因?

np8igboo

np8igboo1#

你在宣布 ResourcelessTransactionManager 在spring批处理中默认使用的bean。由于此事务管理器不创建任何事务,因此hibernate项目编写器将失败并出现此错误。
您需要配置spring批处理以使用 HibernateTransactionManager (然后拆下 ResourcelessTransactionManager ). 这可以使用本文文档中提到的自定义批处理配置器来完成。在你的例子中,可能是这样的:

@Bean
public BatchConfigurer batchConfigurer(DataSource ds, SessionFactory sf) {
    return new DefaultBatchConfigurer(ds) {
        @Override
        public PlatformTransactionManager getTransactionManager() {
            return new HibernateTransactionManager(sf);
        }
    };
}

相关问题