场景一:比如“抢口罩”活动,提交成功后,N天无需重复提交...
场景二:比如发表评论操作,一般是提交成功后,30min后才能再次评论...
功能实现
保证两点
- 1=不能重复提交(用setIfAbsent塞入缓存,如果有指定的key,设值失败,只有没有指定的key时,设值才会成功,而且是原子性的操作,适合高并发的情景,N个并发过来的请求只会有一个进入方法体内)
- 2=成功塞入缓存后,设定TTL,保证只能在TTL时间后才能过期失效(也就意味着TTL之后才能再次提交)
Controller之中的方法
@RequestMapping(value = "repeat", method = RequestMethod.POST)
public BaseResponse repeat(@RequestParam Integer userId, @RequestParam String content){
BaseResponse response = new BaseResponse(StatusCode.Success);
try{
//TODO:第一次要评论成功,但是并发而来的提交上来的信息要间隔ttl才能再次塞入缓存
Boolean res = redisTemplate.opsForValue().setIfAbsent(Constant.RedisRepeatKey + userId, content);
if(res){
log.info("----提交评论成功----");
redisTemplate.expire(Constant.RedisRepeatKey+userId, 20, TimeUnit.SECONDS);
//TODO:后续的操作~将评论信息塞入db
}
else{
return new BaseResponse(StatusCode.Fail.getCode(), "您操作多余频繁,请20s后再次提交评论...");
}
}catch (Exception e){
response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
}
return response;
}