Problem description
I encountered a problem some time ago, and the data was confusing when I had repeated requests in my internal system call.
Conditions of occurrence: Accepted a request, and the request was not completed and the same request was accepted, resulting in a data error (if the previous request was completed, there will be no problem accepting the same request immediately)
Problem analysis : It is caused by dirty reading of the database
Problem solving ideas
1. Add a big lock (it is the easiest way to implement it, but the performance is worrying and it will block requests)
2. Implement request interception (can be shared, but how to implement it is a problem, how to implement it in an elegant way and facilitate reuse)
3. Modify and implement (changes will be made to the original code, which is risky, and the most important thing is that it cannot be shared)
Final implementation method
Implemented by annotation +spring AOP
use
NotDuplicate on any method
Class 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)@Documentedpublic @interface NotDuplicate {}Category 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@Componentpublic class NotDuplicateAop { private static final Set<String> KEY = new ConcurrentSkipListSet<>(); @Pointcut("@annotation(com.hhly.skeleton.base.filter.NotDuplicate)") public void duplicate() { } /** * Parameter verification after method intercepting* @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()); //Split signature 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("This method is being executed and cannot be repeated"); } try { return pjp.proceed(); } finally { KEY.remove(sign); } }}The above is all the content and related codes that I told you this time. If you have any questions, you can discuss them in the comment area below. Thank you for your support for Wulin.com.