Java Reference
In-Depth Information
call if the exception was recoverable. The trouble with this approach is that it clut-
ters the client code with exception-handling logic. Every call that could poten-
tially throw a recoverable exception would be wrapped with the same code. A
much better approach is to centralize the retry logic in a Spring
AOP
interceptor
that retries transactions automatically. Let's take a look.
12.4.1
Using an AOP interceptor to retry transactions
A Spring application can use a custom
AOP
interceptor to catch the
Concurrency-
FailureException
and automatically retry the transaction. Here is a custom
Spring
AOP
interceptor that does this:
public class TransactionRetryInterceptor
implements MethodInterceptor {
protected int maxRetryCount = 3;
public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
public Object invoke(MethodInvocation invocation)
throws Throwable {
int retryCount = 0;
while (true)
try {
ReflectiveMethodInvocation inv =
(ReflectiveMethodInvocation) invocation;
MethodInvocation anotherInvocation = inv.invocableClone();
return anotherInvocation.proceed();
} catch (ConcurrencyFailureException e) {
if (retryCount++ > maxRetryCount)
throw e;
else {
continue;
}
}
}
}
This class has a
maxRetryCount
property whose default value is
3
. The
invoke()
method catches the
ConcurrencyFailureException
and loops at most
maxRetry-
Count
times, retrying the transaction. Because
proceed()
can only be called once,
invoke()
clones the
MethodInvocation
before calling it. The
TransactionRetry-
Interceptor
is a good example of the power and flexibility of the Spring framework.
Search WWH ::
Custom Search