Maybe you should take a look at Spring Aspect support. What you are describing is trying again (permanent) deferment, and most likely you will end up needing it somewhere else, whether itβs a conversation with a web service, an email server, or any other complex system prone to temporary failures .
For example, this simple method calls the base method up to maxAttempts whenever an exception is thrown, unless it is a Throwable subclass specified in noRetryFor.
private Object doRetryWithExponentialBackoff(ProceedingJoinPoint pjp, int maxAttempts, Class<? extends Throwable>[] noRetryFor) throws Throwable { Throwable lastThrowable = null; for (int attempts = 0; attempts < maxAttempts; attempts++) { try { pauseExponentially(attempts, lastThrowable); return pjp.proceed(); } catch (Throwable t) { lastThrowable = t; for (Class<? extends Throwable> noRetryThrowable : noRetryFor) { if (noRetryThrowable.isAssignableFrom(t.getClass())) { throw t; } } } } throw lastThrowable; } private void pauseExponentially(int attempts, Throwable lastThrowable) { if (attempts == 0) return; long delay = (long) (Math.random() * (Math.pow(4, attempts) * 100L)); log.warn("Retriable error detected, will retry in " + delay + "ms, attempts thus far: " + attempts, lastThrowable); try { Thread.sleep(delay); } catch (InterruptedException e) {
This tip can be applied to any bean that you want to use with Spring Aspect support. See http://static.springsource.org/spring/docs/2.5.x/reference/aop.html for more details.
source share