storedprocedureitemreader无法重试死锁异常

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

我很难让我的storedprocedureitemreader在由于数据库死锁异常而失败后重试。
以下是步骤流程的配置:

  1. @Bean
  2. public Step Step() throws Exception {
  3. return stepBuilderFactory.get("Step")
  4. .<Student, Student>chunk(100)
  5. .reader(storedProcItemReader())
  6. .processor(studentItemProcessor)
  7. .writer(fileItemWriter())
  8. .faultTolerant()
  9. .retryLimit(5)
  10. .retry(myException.class)
  11. .backOffPolicy(backoffPolicy())
  12. .build();
  13. }
  14. @Bean
  15. @StepScope
  16. public StoredProcedureItemReader<Student> storedProcItemReader() throws Exception {
  17. return studentItemReader.getDataFromDatabase(dataSource);
  18. }

studentitemreader类文件:

  1. @Component
  2. @StepScope
  3. public class studentItemReader{
  4. @Retryable(include = {DataAccessException.class, JDBCException.class, TransactionException.class, DeadlockLoserDataAccessException.class, Exception.class }, maxAttempts = 5, backoff = @Backoff(delay = 1000,
  5. maxDelay = 15000, multiplier = 2))
  6. public StoredProcedureItemReader<Student> getDataFromDatabase(DataSource dataSource) {
  7. StoredProcedureItemReader<RegionResponse> reader = new StoredProcedureItemReader<>();
  8. SqlParameter[] parameter = { new SqlParameter("@studentId",
  9. java.sql.Types.INTEGER) };
  10. PreparedStatementSetter statementValues = new PreparedStatementSetter() {
  11. @Override
  12. public void setValues(PreparedStatement ps) throws SQLException {
  13. ps.setInt(1, parameterValue);
  14. }
  15. };
  16. reader.setDataSource(dataSource);
  17. reader.setProcedureName("dbo.StudentReport");
  18. reader.setParameters(parameter);
  19. reader.setPreparedStatementSetter(statementValues);
  20. reader.setRowMapper(new StudentRowMapper());
  21. return reader;
  22. }
  23. }
  24. }

所以,问题是在添加了retry之后,我无法让retry条目在storedprocedureitemreader上工作。请告诉我我犯了什么错误。提前谢谢!

lyr7nygr

lyr7nygr1#

您正在添加 @Retryable 在返回项读取器的方法上。此方法仅在配置时调用。如果要在运行时每当抛出异常时重试读取操作,则应在 read 你的读者的方法。添加重试功能的基于注解的方法可能很棘手,这就是为什么我建议使用编程方式来查看实际重试发生的位置。下面是一个简单的例子:

  1. import org.springframework.batch.item.ExecutionContext;
  2. import org.springframework.batch.item.ItemStreamException;
  3. import org.springframework.batch.item.ItemStreamReader;
  4. import org.springframework.batch.item.database.StoredProcedureItemReader;
  5. import org.springframework.retry.support.RetryTemplate;
  6. public class RetryableItemReader<T> implements ItemStreamReader<T> {
  7. private final StoredProcedureItemReader<T> delegate;
  8. private final RetryTemplate retryTemplate;
  9. public RetryableItemReader(StoredProcedureItemReader<T> delegate, RetryTemplate retryTemplate) {
  10. this.delegate = delegate;
  11. this.retryTemplate = retryTemplate;
  12. }
  13. @Override
  14. public T read() throws Exception {
  15. return retryTemplate.execute(context -> delegate.read());
  16. }
  17. @Override
  18. public void open(ExecutionContext executionContext) throws ItemStreamException {
  19. delegate.open(executionContext);
  20. }
  21. @Override
  22. public void update(ExecutionContext executionContext) throws ItemStreamException {
  23. delegate.update(executionContext);
  24. }
  25. @Override
  26. public void close() throws ItemStreamException {
  27. delegate.close();
  28. }
  29. }

然后可以在步骤中将其用作项目读取器:

  1. @Bean
  2. @StepScope
  3. public RetryableItemReader<Student> storedProcItemReader() {
  4. RetryTemplate retryTemplate = new RetryTemplateBuilder()
  5. // define your retry policy
  6. .build();
  7. StoredProcedureItemReader<Student> delegateItemReader = new StoredProcedureItemReaderBuilder<Student>()
  8. // define your delegate item reader
  9. .build();
  10. return new RetryableItemReader<>(delegateItemReader, retryTemplate);
  11. }
展开查看全部

相关问题