本文介绍了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无法重试死锁异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 06:04