本文介绍了StoredProcedureItemReader无法重试死锁异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
由于数据库上的死锁异常,一旦StoredProcedureItemReader失败,我在让它重试时遇到困难。
以下是我的步骤流程的配置:
@Bean
public Step Step() throws Exception {
return stepBuilderFactory.get("Step")
.<Student, Student>chunk(100)
.reader(storedProcItemReader())
.processor(studentItemProcessor)
.writer(fileItemWriter())
.faultTolerant()
.retryLimit(5)
.retry(myException.class)
.backOffPolicy(backoffPolicy())
.build();
}
@Bean
@StepScope
public StoredProcedureItemReader<Student> storedProcItemReader() throws Exception {
return studentItemReader.getDataFromDatabase(dataSource);
}
StudentItemReader类文件:
@Component
@StepScope
public class studentItemReader{
@Retryable(include = {DataAccessException.class, JDBCException.class, TransactionException.class, DeadlockLoserDataAccessException.class, Exception.class }, maxAttempts = 5, backoff = @Backoff(delay = 1000,
maxDelay = 15000, multiplier = 2))
public StoredProcedureItemReader<Student> getDataFromDatabase(DataSource dataSource) {
StoredProcedureItemReader<RegionResponse> reader = new StoredProcedureItemReader<>();
SqlParameter[] parameter = { new SqlParameter("@studentId",
java.sql.Types.INTEGER) };
PreparedStatementSetter statementValues = new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setInt(1, parameterValue);
}
};
reader.setDataSource(dataSource);
reader.setProcedureName("dbo.StudentReport");
reader.setParameters(parameter);
reader.setPreparedStatementSetter(statementValues);
reader.setRowMapper(new StudentRowMapper());
return reader;
}
}
}
所以,问题是在我的StoredProcedureItemReader上添加重试后,我无法让重试部分工作。请告诉我我在这里做错了什么。提前感谢!
推荐答案
您正在向返回项读取器的方法添加@Retryable
。此方法仅在配置时调用。如果希望在每次引发异常时在运行时重试读取操作,则应该在读取器的read
方法上添加注释。添加重试功能的基于注释的方法可能很棘手,这就是为什么我建议使用编程方法来查看实际重试发生在哪里。下面是一个简单的例子:
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamReader;
import org.springframework.batch.item.database.StoredProcedureItemReader;
import org.springframework.retry.support.RetryTemplate;
public class RetryableItemReader<T> implements ItemStreamReader<T> {
private final StoredProcedureItemReader<T> delegate;
private final RetryTemplate retryTemplate;
public RetryableItemReader(StoredProcedureItemReader<T> delegate, RetryTemplate retryTemplate) {
this.delegate = delegate;
this.retryTemplate = retryTemplate;
}
@Override
public T read() throws Exception {
return retryTemplate.execute(context -> delegate.read());
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
delegate.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
delegate.update(executionContext);
}
@Override
public void close() throws ItemStreamException {
delegate.close();
}
}
然后您可以在您的步骤中将其用作项目阅读器:
@Bean
@StepScope
public RetryableItemReader<Student> storedProcItemReader() {
RetryTemplate retryTemplate = new RetryTemplateBuilder()
// define your retry policy
.build();
StoredProcedureItemReader<Student> delegateItemReader = new StoredProcedureItemReaderBuilder<Student>()
// define your delegate item reader
.build();
return new RetryableItemReader<>(delegateItemReader, retryTemplate);
}
这篇关于StoredProcedureItemReader无法重试死锁异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!