【防止重复提交】Redis + AOP + 注解的方式实现分布式锁
在实现分布式锁的情况下,可以使用Redis和AOP(面向切面编程)来防止重复提交。以下是一个简化的示例代码:
首先,定义一个自定义注解来标记需要防重复提交的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
String key() default "";
long timeout() default 10000;
}
然后,创建一个AOP切面来处理这个注解:
@Aspect
@Component
public class NoRepeatSubmitAspect {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Around("@annotation(noRepeatSubmit)")
public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {
// 生成唯一的key
String key = UUID.randomUUID().toString();
try {
// 尝试设置锁,如果返回true,则获取锁成功
if (redisTemplate.opsForValue().setIfAbsent(key, "lock", noRepeatSubmit.timeout(), TimeUnit.MILLISECONDS)) {
return joinPoint.proceed(); // 执行方法
} else {
// 如果已经有锁,则不执行方法,并返回错误提示
return "Repeat submit, please try again later.";
}
} finally {
// 方法执行后,无论成功或者异常,都需要释放锁
redisTemplate.delete(key);
}
}
}
最后,在需要防止重复提交的方法上使用@NoRepeatSubmit
注解:
@RestController
public class SomeController {
@NoRepeatSubmit(timeout = 10000)
@PostMapping("/submit")
public String submit() {
// 方法的逻辑
return "Submit success";
}
}
这样,每当有请求进入submit
方法时,AOP切面会检查Redis中是否存在相应的key。如果不存在,它会在Redis中设置一个键,并执行方法。如果键已经存在,它会返回一个提示,表明方法已被执行。这种方式可以防止在分布式环境中的重复请求。
评论已关闭