重试处理 - 重试策略
在RetryTemplate
里面,执行excuter
方法是重试还是失败是由RetryPolicy
决定的,这也是一个RetryContext
工厂.这个RetryTemplate
有责任使用当前的策略创建一个RetryContext
并且把它注入到RetryCallback
在每一次尝试中。回调失败后RetryTemplate
必须由RetryPolicy
决定使其更新状态(存储在RetryContext
中),然后它询问策略是否会作出其他决定。如果不能作出其他决定,(例如达到极限或超时),政策有责任处理这个状态。简单的操作将会抛出异常它会引起封闭事务的回滚。更多更复杂的操作可能会采取一些回复操作,在这种情况下,事务可以保持不变。
提示
失败是固有的,无论重试与否,如果在业务逻辑中总是抛出相同的异常。这不能帮助重试它。所以不要重试所有异常类型,试着只关注那些你期望可能重试的异常,它虽然对业务逻辑重试变得更具侵略性,但是它没有危害性。如果你事先知道它会失败还去花些时间来证明,只是浪费时间。
Spring Batch
提供给无状态RetryPolicy
一些简单通用的实现,例如SimpleRetryPolicy
,和在上面的示例中使用的TimeoutRetryPolicy
。
SimpleRetryPolicy
只允许重试一些异常类型的命名列表,它也有一个“fatal”
的异常列表,不应重试.并且这个列表重写了retryable
的列表,以便它可以用来很好地控制重试行为:
SimpleRetryPolicy policy = new SimpleRetryPolicy();
// Set the max retry attempts
policy.setMaxAttempts(5);
// Retry on all exceptions (this is the default)
policy.setRetryableExceptions(new Class[] {Exception.class});
// ... but never retry IllegalStateException
policy.setFatalExceptions(new Class[] {IllegalStateException.class});
// Use the policy...
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(policy);
template.execute(new RetryCallback<Foo>() {
public Foo doWithRetry(RetryContext context) {
// business logic here
}
});
还有一个更灵活的实现叫ExceptionClassifierRetryPolicy
。它允许用户配置不同的重试行为为了一组固定的异常类型集合,虽然ExceptionClassifier
抽象类型,分类器上的政策是通过调用异常转换为一个委托RetryPolicy,举个例子,一个异常类型能比映射不通的策略重试更多的次数。
用户需要为更多的客户定制的决定实施他们自己重试策略。例如,如果有一个清楚的详细的解决方案,是归类到可以重试还是不可以重试