利用redis解决防重复提交问题

解决网络延迟下的重复请求:AOP+Redis实现并发控制
本文探讨了在网络延迟导致用户多次点击时,如何通过自定义注解和AOP技术结合Redis来实现请求限频,确保同一用户在设定时间内只能发送一次请求。作者详细介绍了如何配置依赖、应用注解、编写切面,并强调了使用Redis原子操作的重要性。

最近遇到个问题是在网络延迟的时候,用户多次点击,最后这几次请求都发送到了服务器访问相关的接口,最后执行插入。

既然知道了原因,该如何解决。当时我的第一想法就是用注解 + AOP。通过在自定义注解里定义一些相关的字段,比如过期时间即该时间内同一用户不能重复提交请求。然后把注解按需加在接口上,最后在拦截器里判断接口上是否有该接口,如果存在则拦截。

解决了这个问题那还需要解决另一个问题,就是怎么判断当前用户限定时间内访问了当前接口。其实这个也简单,可以使用Redis来做,用户名 + 接口 + 参数啥的作为唯一键,然后这个键的过期时间设置为注解里过期字段的值。设置一个过期时间可以让键过期自动释放,不然如果线程突然歇逼,该接口就一直不能访问。
这样还需要注意的一个问题是,如果你先去Redis获取这个键,然后判断这个键不存在则设置键;存在则说明还没到访问时间,返回提示。这个思路是没错的,但这样如果获取和设置分成两个操作,就不满足原子性了,那么在多线程下是会出错的。所以这样需要把俩操作变成一个原子操作。

1.导入依赖

 <dependency> 

    <groupId>org.redisson</groupId>

     <artifactId>redisson-spring-boot-starter</artifactId> 

    <version>3.15.0</version> 

    </dependency>

2.使用注解

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME) 

@Documented 

public @interface NoRepeat {
   
    

/**

* 锁名称

*/ 

String lockName() default "no-repeat-default-lock-"; 

/**

* 参数key,支持Spel 

*/

String key() default "";

/**

* 获取锁的最长时间,单位默认为秒 

*/ 

long waitTime() default 5;

/**

* 租赁时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值