13

一部のデータベース操作にSpring-Retryを使用しています。I では 3 回再試行しSQLRecoverableExceptionます (これは、3 回失敗した場合に例外の原因が非一時的であると想定しています)、SQLTransientExceptionI では無期限に再試行します (プログラムはデータベースにアクセスしないと何もできないため、そうする方がよい場合もあります)。ユーザーがサーバーを再起動することを決定するまで再試行し続けます)、その他の例外では再試行しません。基本再試行が 100 ミリ秒、最大再試行が 30,000 ミリ秒の指数バックオフ ポリシーを使用しています。

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;
}

理想的には、すべての に対して 100 ミリ秒の固定バックオフを使用しSQLRecoverableExceptions、指数バックオフ ポリシーのみを に適用したいと考えていSQLTransientExceptionsます。ネストされた再試行でこれを達成できますが、コードの複雑さが大幅に増加します。他にオプションがない場合、単純に指数バックオフをSQLRecoverableExceptionSQLTransientException例外の両方に適用することをお勧めします。

単一の再試行テンプレートを使用して、さまざまなバックオフ ポリシーをさまざまな例外に適用する方法はありますか?

4

3 に答える 3

7

確かに、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 );
于 2015-09-01T07:05:03.877 に答える