#spring-data-jpa #spring-data #spring-batch
#весна-данные-jpa #весна-данные #пружинная партия
Вопрос:
Причина первоначального исключения заключается в том, что
o.h.engine.jdbc.spi.SqlExceptionHelper: ОШИБКА: повторяющееся значение ключа нарушает уникальное ограничение «sales_update_request_pkey»
После этого,
исключение org.springframework.dao.OptimisticLockingFailureException: Попытка обновить идентификатор выполнения шага = 3185 с неверной версией (281), где текущая версия 284
Очевидно, это произошло из-за режима многопоточности. Так как в однопоточном режиме все работает так, как должно.
После этого выполнение задания останавливается, а сам шаг, на котором произошла ошибка, помечается в репозитории со статусом Сбой.
Как правильно обработать такую ошибку, чтобы выполнение работы не останавливалось.
Конфигурация шага:
@Bean(name = "createSalesQueueStep") public Step createSalesQueueStep() { return stepBuilderFactory.get("createSalesQueueStep") .lt;SalesRequest, SalesRequestgt;chunk(batchParameters.getPageSize()) .reader(salesRequestReader) .writer(salesRequestWriter) .faultTolerant() .skipLimit(batchParameters.getSkipLimit()) .skip(Exception.class) .taskExecutor(taskExecutor) .build(); } @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(batchParameters.getPull()); taskExecutor.setMaxPoolSize(batchParameters.getPull()); taskExecutor.setWaitForTasksToCompleteOnShutdown(true); taskExecutor.initialize(); return taskExecutor; } @StepScope @Component public class SalesRequestReader extends RepositoryItemReaderlt;SalesRequestgt; { public SalesRequestReader(SalesRequestRepository salesRequestRepository, BatchParameters batchParameters) { super(); this.setSaveState(false); this.setRepository(salesRequestRepository); this.setMethodName("getSalesRequests"); this.setPageSize(batchParameters.getPageSize()); final Maplt;String, Sort.Directiongt; sorts = new HashMaplt;gt;(); sorts.put(SalesRequest_.PRODUCT_CODE, Sort.Direction.ASC); this.setSort(sorts); } } @StepScope @Component @RequiredArgsConstructor public class SalesRequestWriter implements ItemWriterlt;SalesRequestgt; { private final SalesRequestRepository salesRequestRepository; @Override public void write(Listlt;? extends SalesRequestgt; requests) throws Exception { salesRequestRepository.saveAll(requests); } }
Может быть, существует более оптимальный (правильный подход) многопоточное пошаговое выполнение?
Комментарии:
1. Вы пробовали завернуть своего читателя в
SynchronizedItemStreamReader
?