开发笔记-幂等性
1 什么是幂等性?
幂等性的含义是指相同的参数重复请求,但是结果是一致的。
解释:
1.1 相同的参数,就是多次请求参数是一致的,这个是前提条件;
1.2 重复,这个是说场景,针对同一个函数多次用相同的参数进行请求;
1.3 结果,具体有哪些结果呢?针对角色来说:每次操作,分为后端执行的结果(操作副作用,对数据资源的修改)和前端调用后的结果。排除网络超时问题,每次前后端结果每次保持一致。
注:每次后端对资源的操作副作用必须一致,返回值可以不同(根据业务和前端协商)。
2 需要保持幂等性的场景:
2.1 分布式服务中,上游调用下游接口失败后上游多次重试,MQ消费时配置了重试(是否需要重复消息根据业务定)等;
2.2 用户多次重复点击支付,下单,领券等;
一般是对数据重复问题比较敏感的场景,在电商业务中比较多也很重要。比如领券,下单支付等。
3 业务中哪些操作场景需要幂等性?
按照增删改查区分:
3.1 查询操作
查询数据操作具有幂等性,没有对数据资源处理;
3.2 涉及到增删改操作
可能会出现幂等性问题需要处理;
4 处理方案:
4.1 避免重复操作
前端处理:避免重复操作,操作一次按钮置灰;或者跳转到结果页;
4.2 过滤重复请求参数
方式一:
1使用redis分布式锁,上游唯一请求id作为key;
方式二:
1后端提供生成token接口,token放入redis中;
2前端每次调用获取token后再发起业务请求;
3后端接受请求后先删除token成功后再处理业务逻辑,删除失败给客户端提示;
方式三:
新建防重表;
4.3 限制数据修改条件
唯一索引:数据库中如订单id作为唯一索引,根据唯一索引查询,如果存在数据说明已保存成功,后面重复请求直接返回查询结果就行;
悲观锁:数据库同一个事务中使用select for update;注意 for update 要用在索引上,不然会锁表;
乐观锁:每次更新操作时,通过验证某个字段值判断是否需要更新,如加version字段进行判断;
总结:处理方式其实是尽量避免重复请求,还有如何判断重复请求,并对重复请求过滤。开发业务代码时上面3个方向都需要做处理,才能尽可能的保证可靠性。如数据库表根据业务字段唯一索引,代码中使用分布式锁,前端在用户操作时按钮置灰。