Привет, я получаю бесконечный цикл при возникновении исключения.Что-то не так с менеджером транзакций, который я использую?Спасибо!Ниже приведены настройки моей работы
@Bean
public ItemReader<Entity> bizAppReader() {
@SuppressWarnings("serial")
Map<String, Object> map = new HashMap<String, Object>() {{
put("status", Arrays.asList(new ApplicationStatus[] {ApplicationStatus.COMPLETED, ApplicationStatus.PENDING, ApplicationStatus.INITIATE}));
}};
return new JpaPagingItemReaderBuilder<Entity>()
.name("bizAppJpaReader")
.entityManagerFactory(entityManagerFactory)
.queryString("from Entity b where b.status in (:status)").parameterValues(map)
.build();
}
@Bean
public Step bizApplicatonStep(@Value("${batch.chunk_size:10}") int chunkSize,
ItemReader<Entity> bizAppReader,
ItemProcessor<Entity, Map<ApplicationStatus, String>> bizAppProcessor,
ItemWriter<Map<ApplicationStatus, String>> bizAppWriter) {
return stepBuilderFactory.get("bizApplicatonStep")
.<Entity, Map<ApplicationStatus, String>>chunk(chunkSize).reader(bizAppReader)
.processor(bizAppProcessor).writer(bizAppWriter)
.faultTolerant()
.skip(Exception.class)
.noRollback(Exception.class)
.skipPolicy((e, i) -> {
log.error("Exception occurred : ", e);
return true;
})
.allowStartIfComplete(true)
.build();
}
@Slf4j
@SpringBootApplication
@EnableBatchProcessing
public class BatchApplication extends DefaultBatchConfigurer {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(BatchApplication.class, args);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job;
JobParameters jobParameters;
if (ArrayUtils.isNotEmpty(args) && args[0].equals("bookingJob")) {
job = context.getBean("bookingJob", Job.class);
jobParameters = new JobParametersBuilder()
.addString("startMonth", args[1])
.addString("endMonth", args[2])
.toJobParameters();
} else {
job = context.getBean("bizApplicationJob", Job.class);
jobParameters = new JobParametersBuilder().toJobParameters();
}
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
if (BatchStatus.FAILED.equals(jobExecution.getStatus())) {
log.error("job execution completed exit code is : 1 ");
System.exit(1);
}
log.info("job execution completed exit code is : 0 ");
}
@Override
protected JobRepository createJobRepository() throws Exception {
return new MapJobRepositoryFactoryBean(new ResourcelessTransactionManager()).getObject();
}
}
Stacktrace:
10:13:20.657 [main] ERROR c.u.pweb.bizacct.batch.BizJobConfig - Exception occurred :
java.lang.IllegalStateException: Transaction already active
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
- ==================== Обновление приложения доповторить =====================
это происходит, если читателю не удалось прочитать недопустимое значение Enum из БД.
@Slf4j
@SpringBootApplication
@EnableBatchProcessing
public class DemoBatchApplication extends DefaultBatchConfigurer {
public static void main(String[] args) {
SpringApplication.run(DemoBatchApplication.class, args);
}
@Override
public void setDataSource(DataSource dataSource) {
super.setDataSource(null);
}
private final EntityManagerFactory entityManagerFactory;
public DemoBatchApplication(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Override
public PlatformTransactionManager getTransactionManager() {
return new JpaTransactionManager(this.entityManagerFactory);
}
}
enum
public enum ApplicationStatus {
MA, AS, SH, CP, AA, AP
}
таблица
@Entity
@Table(name = "APP_TBL_TEST")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ApplicationEntity {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "ID", length = 50)
private String id;
@Column(name = "APPLICATION_NAME", unique = true, length = 50)
private String referenceNumber;
@Column(name = "STATUS")
@Enumerated(EnumType.STRING)
private ApplicationStatus status;
}
пакетная конфигурация
@Configuration
@Slf4j
@Data
public class ApplicationBatchCfg {
@Autowired
public EntityManagerFactory entityManagerFactory;
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public Step applicationStep(@Value("${batch.chunk_size:5}") int chunkSize,
ItemReader<ApplicationEntity> appReader,
ItemProcessor<ApplicationEntity, String> appProcessor,
ItemWriter<String> appWriter){
return stepBuilderFactory.get("applicatonStep")
.<ApplicationEntity, String>chunk(chunkSize)
.reader(appReader)
.processor(appProcessor)
.writer(appWriter)
.faultTolerant()
.skip(Exception.class)
.noRollback(Exception.class)
.skipPolicy((e, i) -> {
log.error("Exception occurred : ", e);
return true;
})
.skipLimit(5)
.allowStartIfComplete(true)
.build();
}
@Bean
public Job applicationJob(Step applicationStep) {
return jobBuilderFactory.get("applicationJob").incrementer(new RunIdIncrementer())
.start(applicationStep).build();
}
@Bean
public ItemReader<ApplicationEntity> appReader() {
return new JpaPagingItemReaderBuilder<ApplicationEntity>()
.name("appReader")
.entityManagerFactory(entityManagerFactory)
.queryString("from ApplicationEntity")
.pageSize(3)
.build();
}
@Bean
public ItemProcessor<ApplicationEntity, String> appProcessor(){
return new ItemProcessor<ApplicationEntity, String>() {
@Override
public String process(ApplicationEntity item) throws Exception {
//nothing for demo only
log.info("item {}", item);
return null;
}
};
}
@Bean
public ItemWriter<String> appWriter() {
return new ItemWriter<String>() {
@Override
public void write(List<? extends String> items) throws Exception {
//nothing for demo only
}
};
}
}
внутри yml
spring:
jpa:
properties:
hibernate:
show_sql: true
use_sql_comments : true
format_sql: true
dialect: org.hibernate.dialect.Oracle10gDialect
datasource:
useWallet: false
url: jdbc:oracle:thin:@DB12397:1521:azd
platform: oracle
username: user
password: pwd