자바 병렬 접근 중복 요청 필터 문제

2935 단어 자바동시 방문
문제 설명
얼마 전에 문제 가 생 겨 서 내부 시스템 호출 에 중복 요청 이 발생 하여 데이터 가 혼 란 스 러 웠 습 니 다.
발생 조건:요청 을 받 았 습 니 다.이 요청 은 완료 되 지 않 았 고 같은 요청 을 받 아 데이터 오류 가 발생 했 습 니 다.(이전 요청 이 완료 되 었 다 면 바로 같은 요청 을 받 아들 이 는 데 문제 가 없 을 것 입 니 다)
문제 분석:데이터베이스 의 더러 운 읽 기 때문에
문제 해결 방향
1.큰 자 물 쇠 를 추가 합 니 다.(가장 간단 한 실현 방식 이지 만 성능 이 걱정 스 럽 고 요청 을 막 을 수 있 습 니 다)
2.요청 차단 실현(공용 은 가능 하지만 어떻게 실현 하 느 냐 가 문제 입 니 다.우아 한 방식 으로 어떻게 실현 하 느 냐 가 문제 이 고 재 활용 이 편리 합 니 다)
3.수정 실현(기 존 코드 를 변경 할 수 있 고 위험 이 존재 하 며 가장 중요 한 것 은 공유 할 수 없다)
최종 실현 방식
주석+spring AOP 방식 으로 구현
쓰다
임의의 방법 에 주석 을 추가 합 니 다 NotDuplicate
클래스 1:

import static java.lang.annotation.ElementType.METHOD;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NotDuplicate {
}
클래스 2:

import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;



@Aspect
@Component
public class NotDuplicateAop {

  private static final Set<String> KEY = new ConcurrentSkipListSet<>();

  @Pointcut("@annotation(com.hhly.skeleton.base.filter.NotDuplicate)")
  public void duplicate() {
  }

  /**
   *             
   * @param pjp
   * @return
   * @throws Throwable
   */
  @Around("duplicate()")
  public Object duplicate(ProceedingJoinPoint pjp) throws Throwable {
    MethodSignature msig = (MethodSignature) pjp.getSignature();
    Method currentMethod = pjp.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes());
    //    
    StringBuilder sb = new StringBuilder(currentMethod.toString());
    Object[] args = pjp.getArgs();
    for (Object object : args) {
      if(object != null){
        sb.append(object.getClass().toString());
        sb.append(object.toString());
      }
    }
    String sign = sb.toString();
    boolean success = KEY.add(sign);
    if(!success){
      throw new ServiceRuntimeException("       ,      ");
    }
    try {
      return pjp.proceed();
    } finally {
      KEY.remove(sign);
    }

  }
}
이상 은 이번에 여러분 께 말씀 드 린 모든 내용 과 관련 코드 입 니 다.만약 에 여러분 이 아래 의 댓 글 에서 토론 할 수 있 는 문제 가 있다 면 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기