1. 问题
如果我们在短时间内多次点击提交的接口,一般的情况是如下的流程:
正常流程
找到用户后提示信息
单个信息是正常的,但如果用户在短时间内多次点击,如下图,两个相同的信息同时过来,第一个还没有来得及保存,第二个已经同时开始查询了,这里就会出现同一个数据会被多次保存。多次提交的示意图
2. 解决思路
这里可能有人会问到,那这个主键是不是记录到了redis中会一直存在吗?不会的,因为这里使用到的redis的特性,记录的过期时间,设定好30秒过期时间就可以,这里也就是说,如果30秒内,用户提交的数据主键是相同的,我们就认为是重复提交的无用数据,给用户相关的提示就可以了
3. 代码解读 如下图,这里是自定义了一个注解@RepeattAnnoatation,可以放到api的方法上面。RepeatSubmitInterceptor是拦截类,用于做注解的解析。从注解那里获取到有用的定义的主健是什么,从入参那里取到相应的数据,并可以根据 这个来判断是否有重复,并确认重复后应当如何处理。 这里有一点要说明一下
为什么会有一个BodayReaderWrapper的类
这是因为inputStream的特殊之处,只要在fiter中已经读过一次了,它会将读取的指针指向流的最后,就没有办法再将指针放回到最前面(有人说这里有一个reset可以复位,但我试了一下,没有成功),所以需要copy一个相同的对象出来,给监听器interceptor解析入参中是否有重复的数据。
4. 代码
代码地址参考:gitee.com/wuabc0954/f… 中redislock就是相关的组件,可以直接下载使用,这里如何打成相关的包,我还不会,正在学习中。
使用的方法
遗留问题
这里是还是完美的解决了所有的问题的,答案是否定的,这里其实是还有一个问题没有解决,如果你的方法在过期的时间内还没有完成呢事务呢?但redis中的主键已经过期了,下一个相同的数据过来了,可能又会有重复的数据了。这种可能性可能很低,但也是有可能的,这个后面我再来讲如何处理,提示一下可以使用切面来处理