概念
防重:防止产生重复数据。
幂等:除了防止产生重复数据外,还要求每次请求返回一样的结果。
业务场景
1、点赞
2、加入购物车
3、创建订单
4、扣减库存
5、消息重复消费
6、表单重复提交
解决方案
如果有页面,js控制按钮防重复点击是基本操作
1、用业务逻辑判断
比如如果用户报名,先检查报名表是否有记录,没有记录再插入,并且数据库唯一索引,或者先将业务信息放入redis中,或者用分布式锁。
再比如用户兑奖,接口调用会将用户的中奖流水传入,接口提供方会根据中奖流水判断该流水是否兑奖,若已经兑奖,则直接返回成功,其中用数据库唯一索引或者redis都好。
2、业务无关的方案
本人觉得,业务无关的方案只能防止消息重试,网络抖动自动重试这些业务场景,不能保证用户故意点击发起的场景。方案如下
2-1、请求头加上token,请求之前先获取token再请求,后端如果发现token不存在,则表示重复操作,这种方法更多的是为了防止CSRF漏洞,而不是幂等性。
3-2、接口调用必须要求请求头加一个token,接口处理方将该token用setNx设置到redis中并且设置有效时间,若返回0表示该请求已经请求过了,获取返回结果,若为处理中,则返回处理中,若为成功则返回成功,返回结果可以在业务逻辑处理完后设置。(AOP)