Весенняя спячка 5.4.22.Финал : javax.постоянство.Исключение TransactionRequiredException: при обновлении spring boot транзакция не выполняется

#java #spring #spring-boot #hibernate #jpa

Вопрос:

Я недавно обновил spring boot с 1.5 до 2.3.5, но столкнулся с некоторыми проблемами при сохранении данных. Мое приложение представляет собой пакет spring, который считывает, обрабатывает и записывает данные в базу данных, считыватель и процессор в порядке, но у писателя возникают проблемы. Он отлично работает с версией 1.5 spring boot. Ниже приведен краткий код :

Дозатор.Класс

 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;

  @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(hibernateVCommitProperties());
    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> mylRequestReader() 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")
        .<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 vtoolsDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl(toolsDbConnection);
    dataSource.setUsername(toolsDbUser);
    dataSource.setPassword(toolsDbPass);
    if (log.isInfoEnabled()) {
      //
    }
    return dataSource;
  }
}
 

This works fine with 1.5 but gives below exception in 2.3.5 upgrade of spring boot:

 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.batch.item.database.HibernateItemWriter.write(HibernateItemWriter.java:95)
    at org.springframework.batch.item.database.HibernateItemWriter$FastClassBySpringCGLIB$1177da25.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    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.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at org.springframework.batch.item.database.HibernateItemWriter$EnhancerBySpringCGLIB$c0ff7bb9.write(<generated>)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:193)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:159)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:294)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:217)
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
    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 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)
 

Я искал что-то подобное в StackOverflow, но ничего не помогло.

Я внес следующие изменения в файл свойств

 spring.main.allow-bean-definition-overriding=true
 

потому что я получал где-то «Не могу создать боб, боб с тем же именем существует ошибка».

Когда проект строится, я вижу следующую строку :

 2021-04-07 06:43:31.409  WARN 79404 --- [main] o.s.b.c.c.a.DefaultBatchConfigurer       : No transaction manager was provided, using a DataSourceTransactionManager
 

Комментарии:

1. Вы используете a ResourceLessTransactionManager , который в основном утверждает, что вы не используете транзакции. Таким образом, все рухнет. Ошибка, которую вы получили и которую вы «исправили», разрешив переопределение компонентов, является реальной проблемой.

2. он отлично работает в более ранней версии 1.5 spring boot. Что я могу сделать?

3. Это работает по счастливой случайности. Почему вы вообще используете эту транзакционную угрозу? Он вам не понадобится, так как он уже есть, поэтому удалите его.

4. какой из них уже доступен?

5. я не думаю, что ResourceLessTransactionManager используется, если вы видите последнюю строку моего вопроса выше, также я использую writer для записи, который использует источник данных для записи.