接口幂等性的实现

什么是接口幂等性? 就是代码执行一次和n次,产生的结果都是一样的。

防重复提交和接口幂等性的区别:

 

需要处理接口幂等性的情况?

1、select语句天生幂等

2、update语句,需要做幂等处理

3、delete语句,如果是精确删除,如id =1,不需要处理。如果是id>1,则需要

4、insert语句,如果是插入自增的id,比如增加数据,需要处理。如果是,手动填充id,传进实体,则不需要,因为数据库主键有唯一性约束,会报异常。

幂等性的做法:

1、token机制

  • 客户端先发送一个请求去获取token,服务端生成一个token缓存到redis,然后返回给客户单
  • 客户端发起业务请求,携带token。此时,会去缓存里查询是否有token,如果有,则执行业务,业务完成后,删除token。
  • 客户端发起重复业务请求,会去查询缓存,没查到,执行失败。

 注意:判断以及删除token,这两步需要保持原子性,否则会有并发的问题。可以用lua脚本实现。

     全局唯一 ID 可以用百度的 uid-generator、美团的 Leaf 去生成

 

2、利用唯一性约束

1)利用sql主键或者唯一键的唯一性

执行业务的时候,会去数据库的去重表里面插入一条数据,如果插入成功,则执行成功,如果插入失败,则执行失败。

例如: 下单操作,禁止重复下单

解决方案:可以在mysql中定义requestId字段或用生成的orderID作为唯一性约束,然后插入数据。

如果数据已经插入过,会报mysql异常,在捕捉异常的时候返回跟插入数据的一样的结果。又或者在插入前先根据唯一性约束字段去查,如果查到有数据,则返回跟第一次插入同样的结果。

 

2) 基于redis的唯一性

  • 执行业务请求的时候,先去试着插入数据到redis,用setnx命令,如果插入成功,执行业务,插入失败,不执行。

3、状态机

例如,我们tb_activity活动表里面有status字段,那status字段有未发布、活动中、结束等状态,如果此时活动编号为112233这个活动编号的活动status为活动中,再次收到更新状态为活动中的状态的请求,则会执行失败,则返回第一次一样的结果。

例如: select status from tb_activity where activity_code = "112233";

得到status = "活动中";

然后业务代码执行更新语句 update tb_activity set status ="活动中" where  activity_code="112233" and status="未发布";

由于此时编号为112233的活动status为活动中,所以会执行失败,因此,返回影响行数为0,所以我们可以根据返回结果判断而做幂等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值