承接 用AOP实现业务service的重新调用(一),我们继续......
service重试的落地实现
方案A: web业务系统里面有很多action,很多service,如果直接从每个调用service的点入手的话,修改点会很多,而且代码会大量冗余,实现代码并不复杂
try{
//service调用
} catch(UncategorizedSQLException e) {
if(retry) {
//service调用
}
}
方案B: 因为我们使用了spring,所以自然会想到AOP,通过拦截器来拦截service方法的调用,一旦发生UncategorizedSQLException,就重试一次service方法的调用.直接上代码:
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.dao.DataIntegrityViolationException;
public class ServiceRetryAdvice implements MethodInterceptor {
private static ThreadLocal<Integer> retryNum = new ThreadLocal<Integer>() {
public Integer initialValue() {
return 0;
}
};
public Object invoke(MethodInvocation invocation) throws Throwable {
Object returnObject = null;
try{
returnObject = invocation.proceed();
} catch(DataIntegrityViolationException e) {
if (retryNum.get() == 0){
retryNum.set(1);
ReflectiveMethodInvocation refInvocation = (ReflectiveMethodInvocation)invocation;
Object proxy = refInvocation.getProxy();
Method method = refInvocation.getMethod();
Object[] args = refInvocation.getArguments();
returnObject = method.invoke(proxy, args);
} else {
throw e;
}
} finally {
retryNum.remove();
}
return returnObject;
}
}
关于代码的详细说明以及各种需要考虑到的方方面面,请参照
用AOP实现业务service的重新调用(三)