2013-05-29 3 views
0

데이터베이스 상실 연결 문제에 대한 재시도 논리 (max_retries = 5)를 구현하기 위해 @Aspect를 사용하고 있습니다.이 조언에서는 연결을 시도하기 위해 로직 재 시도 횟수를 추적하는 ThreadLocal 객체가 있습니다 부적절한 연결 문제에 대한 무제한 재 시도를 피하기 위해 연결을 얻을 수 없을 때마다 증가하며 최대 재시도 횟수는 5 (상수)입니다.ThreadLocal 및 @Aspect annotation

하지만 문제는이 @Aspect 자바 클래스 ThreadLocal이 결코 증가하지 않는다는 것이며 코드에서 endlees 루프가 발생한다는 것입니다. 물론 최대 횟수 재 시도 후에 다시 시도하지 않아야하지만 그 카운트에 도달하지는 않습니다. while 루프를 벗어나지 마십시오.

@Aspect 및 ThreadLcal 개체에이 문제가있는 경우 알려 주시기 바랍니다.

코드를 공유하게되어 기쁩니다.

private static ThreadLocal<Integer> retryCounter= new ThreadLocal<Integer>() {}; 
private static final String STALE_CONNECTION_EXCEPTION = "com.ibm.websphere.ce.cm.StaleConnectionException"; 

@Around("service") 
public Object retryConnection(ProceedingJoinPoint pjp) throws Throwable { 
     if (staleConnectionException == null) { 
     return pjp.proceed(); 
    } 
    Throwable exception = null; 
    retryCounter.set(new Integer(0)); 
    while (retryCounter.get() < MAX_TRIES) { 
     try { 
      return pjp.proceed(); 
     } 
     catch (AppDataException he) { 
      exception = retry(he.getCause()); 
     } 
     catch (NestedRuntimeException e) { 
      exception = retry(e); 
     } 
    } 
    if (exception != null) { 
     Logs.error("Stale connection exception occurred, no more retries left", this.getClass(), null); 
     logException(pjp, exception); 
     throw new AppDataException(exception); 
    } 
    return null; 
} 

private Throwable retry(Throwable e) throws Throwable { 
    if (e instanceof NestedRuntimeException && ((NestedRuntimeException)e).contains(staleConnectionException)) { 
     retryCounter.set(retryCounter.get()+1); 
     LogUtils.log("Stale connection exception occurred, retrying " + retryCounter.get() + " of " + MAX_TRIES, this.getClass()); 
     return e; 
    } 
    else { 
     throw e; 
    } 
} 
+1

코드를 표시 할 수 있습니까? –

+1

당신은'e instanceof NestedRuntimeException && ((NestedRuntimeException) e) .contains (staleConnectionException)'이 true입니까? 또한, 귀하의 경우에 ThreadLocal을 사용하는 것이 유용한 것은 아니라고 생각합니다. 'retryConnection' 메소드에서 간단한 카운터를 사용하는 것이 어떻습니까? – gma

+0

예 로그에 해당 로그 메시지가 표시됨을 알 수 있습니다. "부실 연결 예외가 발생했습니다. 다시 시도하는 중 1이 5 중 1"입니다. – pk2

답변

1

주석에서 언급했듯이 로컬 스레드를 사용하는 이유를 모르지만 무언가 루프를 일으킬 수있는 요소는이 측면을 재귀 적으로 사용하는 것입니다. 디버거를 통해 실행하거나 프로필을 작성하여 동일한 측면을 중첩 방식으로 사용하는지 확인하십시오.