接口重复提交:是由于网络等原因,造成一瞬间发送多个请求,造成insert,update操作,多次数据被修改。如果多个请求时间间隔足够的小,那么可以理解为并发问题;即并发情况下,只有一次操作成功。
实现原理: 自定义注解+AOP切面+分布式锁。
1.自定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 防止重复提交的注解
*
* @author yxh
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD})
public @interface AvoidRepeatSubmit {
long lockTime() default 1000;
}
2.分布式锁:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yxh on 2022/1/10 18:02
*/
@Component
public class RedisDistributedLock {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public static final String UNLOCK_LUA;
static {
StringBuilder sb = new StringBuilder();
sb.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] ");
sb.append("then ");
sb.append(" return redis.call(\"del\",KEYS[1]) ");
sb.append("else ");
sb.append(" return 0 ");
sb.