分布式核心问题系列目录
--------------------------------------------------------------------------------------------------------------------------
1.什么是接口幂等性
幂等:在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同,即f(f(x)) = f(x)。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。举个例子:在用户填写注册信息发送提交请求时,由于网络卡顿导致用户多次点击“注册”按钮,多个相同的注册请求被发送到了后台,但用户的注册信息在业务上我们只要求保存一份就可以了。当然并不是所有的接口都需要幂等性设计,需要根据具体业务来定,接口幂等性设计可能出现在以下情况中:
(1)请求重复提交
(2)接口超时重试
(3)前端操作抖动
2.幂等性设计的核心思想
核心思想:通过唯一的业务单号保证幂等性,如果不存在唯一业务单号,可以通过让前端发送请求时携带token来解决(下面会分析到) ;在非并发情况下,调用接口前先查询一下该业务单号是否被操作过,没有被操作过则执行接口调用。在并发情况下,就不能只单纯的先查后插,因为可能同一时间查询出来的结果都是没有被操作过,这里可以用唯一业务单号做key,给整个过程加分布式锁。
3.接口幂等性方案
3.1 存在唯一业务号的情况
select:不会对业务数据产生影响,天然幂等
delete: 天然幂等,因为毕竟第一次已经删除,第二次不会有影响。
update:如果是根据唯一业务号直接更新某个值是幂等的,因为每次前端传入需要修改的字段数据都是相同的。但如果是更新“修改次数”这样字段时则是非幂等的,可以在用户调用接口前,先将数据版本号放入前端隐藏域内,用户修改数据的时候将版本号一同提交到后台,后台使用版本号作为更新条件,sql类似如下:
update
tableName
set
version = version + 1,
xxx = #{xxx}
where
id = xxx
and
version = #{version}
利用乐观锁和update行锁来保证接口幂等性。
insert方案:和update一样,insert语句设计的时候也需要重点考虑下幂等性设计,可以通过用唯一业务号申请分布式锁并设置过期时间,业务完成后自动释放锁来保证接口幂等性。
3.2 不存在唯一业务号的情况
update、insert在没有唯一业务号的情况下可以采用在调用接口前,先生成全局唯一的token放入操作页面隐藏域内,用户调用接口时将隐藏域中的token一同传入后台,后台拿到token后去申请分布式锁并设置过期时间,业务完成后自动释放锁来保证接口幂等性。