我正在使用Spring-Retry进行一些数据库操作。在一次SQLRecoverableException
I重试3次(假设它导致失败的原因是,如果导致失败的原因是三次,则导致该异常是非暂时性的),一次SQLTransientException
I重试(该程序在不访问数据库的情况下无法执行任何操作)继续重试,直到用户决定重新引导服务器为止),并且在其他任何例外情况下,我都不会重试。我使用指数退避策略,其基本重试时间为100ms,最大重试时间为30,000ms。
private static final int MAX_RECOVERABLE_RETRIES = 3;
private static final long INITIAL_INTERVAL = 100;
private static final long MAX_INTERVAL = 30 * 1000;
private static final double MULTIPLIER = 2.0;
public static RetryTemplate databaseTemplate() {
RetryTemplate template = new RetryTemplate();
ExceptionClassifierRetryPolicy retryPolicy = new ExceptionClassifierRetryPolicy();
Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();
NeverRetryPolicy baseException = new NeverRetryPolicy();
SimpleRetryPolicy recoverablePolicy = new SimpleRetryPolicy();
recoverablePolicy.setMaxAttempts(MAX_RECOVERABLE_RETRIES);
AlwaysRetryPolicy transientPolicy = new AlwaysRetryPolicy();
policyMap.put(Exception.class, baseException);
policyMap.put(SQLRecoverableException.class, recoverablePolicy);
policyMap.put(SQLTransientException.class, transientPolicy);
retryPolicy.setPolicyMap(policyMap);
template.setRetryPolicy(retryPolicy);
ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
backOffPolicy.setInitialInterval(INITIAL_INTERVAL);
backOffPolicy.setMaxInterval(MAX_INTERVAL);
backOffPolicy.setMultiplier(MULTIPLIER);
template.setBackOffPolicy(backOffPolicy);
return template;
}
理想情况下,我想对所有人都使用100ms的固定补偿SQLRecoverableExceptions
,并且仅将指数补偿策略应用于SQLTransientExceptions
。我可以使用嵌套重试来完成此操作,但这将大大增加代码的复杂性-鉴于没有其他选择,我希望仅将指数退避同时应用于异常SQLRecoverableException
和SQLTransientException
异常。
我是否可以使用一个重试模板将不同的退避策略应用于不同的例外?
确实,ExceptionClassifierRetryPolicy
是要走的路。我没有设法使其与policyMap
虽然。
这是我的用法:
@Component("yourRetryPolicy")
public class YourRetryPolicy extends ExceptionClassifierRetryPolicy
{
@PostConstruct
public void init()
{
final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts( 3 );
this.setExceptionClassifier( new Classifier<Throwable, RetryPolicy>()
{
@Override
public RetryPolicy classify( Throwable classifiable )
{
if ( classifiable instanceof YourException )
{
return new NeverRetryPolicy();
}
// etc...
return simpleRetryPolicy;
}
});
}
}
然后,您只需要在重试模板上进行设置即可:
@Autowired
@Qualifier("yourRetryPolicy")
private YourRetryPolicy yourRetryPolicy;
//...
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy( yourRetryPolicy );
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句