# 接口幂等性设计

## 什么是幂等性

多次请求某一个资源对于资源本身应该具有同样等结果,也就是说,其任意多次执行对资源本身所产生等影响的结果均与第一次执行的影响的结果相同。（多次请求的资源都是相同的导致数据库存储脏数据）

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的，不会因为多次点击而产生了副作用

## 产生幂等性场景

总结一句话就是重复

1. 浏览器重复的HTTP请求：页面重复刷新、使用浏览器后退按钮重复之前的操作、用户双击提交按钮、用户重复操作、使用浏览器历史记录重复提交表单
2. 网络波动, 可能会引起重复请求
3. 应用使用了失效或超时重试机制(Nginx重试、RPC重试或业务层重试等)
4. 重复消息，定时任务重复执行

## 幂等性解决方案

1. 不是所有的业务都需要解决：天然就是幂等性的
2. 幂等性一定是有时效性质的：成本等太高，也没必要
3. 唯一值的设计：比如金额扣减，连续两笔不重复的请求就是扣减相同的金额

幂等性解决：

1. 前端控制
   1. 按钮只可操作一次，按钮Disable、按钮置灰，隐藏，不可点击等方式
2. 应用层控制
   1. Redis的SETNX 或者 数据库防重表insert【前端的token或者业务唯一ID】
   2. 报文或者的待操作数据的MD5或hash
3. 数据库层控制
   1. Select、Delete本身就是幂等性
   2. 新增：使用数据库主键
   3. 修改：
      * 把表中id为XXX的记录的A字段值设置为1,这种操作不管执行多少次都是幂等的
      * 把表中id为XXX的记录的A字段值增加1,这种操作就不是幂等的
