定义:用户同一操作的发起的一次请求或者多次请求都能得到一样的效果
什么时候能使用到幂等
- 前端重复提交
- 接口超时重试(feign等)
- 消息重复消费(例如rabbitmq,如果没有手动ack,那么继续重新投递)
不需要幂等的情况:
- 数据库中的select
- 更新,删除
- 插入的话(分是不是唯一id
解决方案
1. token方案
1、服务端提供了发送 token 的接口。我们在分析业务的时候,哪些业务是存在幂等问题的,
就必须在执行业务前,先去获取 token,服务器会把 token 保存到 redis 中。
2、然后调用业务接口请求时,把 token 携带过去,一般放在请求头部。
3、服务器判断 token 是否存在 redis 中,存在表示第一次请求,然后删除 token,继续执行业
务。
4、如果判断 token 不存在 redis 中,就表示是重复操作,直接返回重复标记给 client,这样
就保证了业务代码,不被重复执行。
2. 加锁
数据库悲观锁
数据库乐观锁:在更新的时候使用(例如更新库存,直接使用版本号
分布式锁
3. 各种唯一约束
- 数据库唯一约束
- redis中的set记录(计算md5)?这个方案看着不太行
- 防重表
-
- 额外建立一个表来记录唯一编号(例如订单id
- 需要注意:应该在同一库中,使用事务来保证一致性,可以回滚