美文网首页
接口幂等性

接口幂等性

作者: 刘敏_15da | 来源:发表于2019-07-09 16:33 被阅读0次

含义:接口可重复调用后,在调用方多次调用的情况下,接口最终得到的结果是一致的。

有些接口天然具备幂等性,如查询接口。

除查询外,增加、更新、删除都要保证幂等性。

如何保证幂等性?

1.全局唯一ID(防止新增脏数据)

如果使用全局唯一ID,就是根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在来判断这个操作是否已经执行,如果不存在则把全局唯一ID存储到存储系统中,比如数据库,redis等,如果存在则表示该方法已经执行。

举例:创建履约单的过程

1)response是根据订单ID和订单类型唯一构建的。

2)创建履约单时,先到表中根据订单ID和订单类型查询response,如果response已经存在,则表示已经创建过履约单,不能再创建,否则创建履约单。

2.去重表

这种方法适用于在业务中有唯一标识的插入场景中。比如在支付场景中,如果一个订单只会支付一次,所以订单ID可以作为唯一标识。这时,我们就可以创建一张去重表,并且把唯一标识作为唯一索引,在我们实现时,把创建支付单据写入去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。

3.插入或更新

插入或有唯一索引的情况,比如关联某商品,其中商品的ID和品类的ID可以构成唯一索引,并且在数据表中也增加了唯一索引。这时候就可以使用insertOrUpdate操作

insert into goods_category (goods_id,category_id,create_time,update_time)

values(#{goodsId},#{categoryId},now(),now())

on DUPLICATE KEY UPDATE

update_time=now()

4.多版本控制

适用于更新的场景,比如更新商品的名字,可以在更新的接口中增加一个版本号,做幂等。

boolean updateGoodsName(int id,String newName,intversion);

实现代码

update goods set name=#{newName},version=#{version} where id=#{id} and version<${version}

5.状态机控制

适用于有状态机流转的情况下,比如订单的创建和付款,订单的付款肯定在前,这时可以通过在设计状态字段时,使用int类型,并且通过值类型的大小做幂等,比如订单的创建为0,付款成功为100,付款失败为99.

update `order` set status=#{status} where id=#{id} andstatus<#{status}

6.token机制:防止页面重复提交

原理上通过session token来实现(也可以通过redis实现)。当客户端请求页面时,服务器会生成一个随机数token,并且将token放到session中,然后将token发给客户端(一般通过构造hidden表单).

下次客户端提交请求时,token会随着表单一起提交到服务器端。

服务器端第一次验证相同之后,会将session中的token值更新下,若用户重复提交,第二次的验证判断将失败,因为用户提交的表单中的token没变,但是服务器端session中token的值已经改变了。

5、悲观锁

获取数据的时候加锁获取。select * from table_xxx where id='xxx' for update; 注意:id字段一定是主键或者唯一索引,不然是锁表,会死人的;悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,根据实际情况选用;

6、乐观锁——乐观锁只是在更新数据那一刻锁表,其他时间不锁表,所以相对于悲观锁,效率更高。乐观锁的实现方式多种多样可以通过version或者其他状态条件:

1. 通过版本号实现update table_xxx set name=#name#,version=version+1 where version=#version#如下图(来自网上);

2. 通过条件限制 update table_xxx set avai_amount=avai_amount-#subAmount# where avai_amount-#subAmount# >= 0要求:quality-#subQuality# >= ,这个情景适合不用版本号,只更新是做数据安全校验,适合库存模型,扣份额和回滚份额,性能更高;

7、分布式锁

如果是分布是系统,构建全局唯一索引比较困难,例如唯一性的字段没法确定,这时候可以引入分布式锁,通过第三方的系统(redis或zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁,这样其实是把多线程并发的锁的思路,引入多多个系统,也就是分布式系统中得解决思路。要点:某个长流程处理过程要求不能并发执行,可以在流程执行之前根据某个标志(用户ID+后缀等)获取分布式锁,其他流程执行时获取锁就会失败,也就是同一时间该流程只能有一个能执行成功,执行完成后,释放分布式锁(分布式锁要第三方系统提供);

8、select + insert

并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行,简单的处理方法是,先查询下一些关键数据,判断是否已经执行过,在进行业务处理,就可以了。注意:核心高并发流程不要用这种方法;

9、状态机幂等

在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机(状态变更图),就是业务单据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机,这时候,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。注意:订单等单据类业务,存在很长的状态流转,一定要深刻理解状态机,对业务系统设计能力提高有很大帮助

10、对外提供接口的api如何保证幂等

如银联提供的付款接口:需要接入商户提交付款请求时附带:source来源,seq序列号;source+seq在数据库里面做唯一索引,防止多次付款(并发时,只能处理一个请求) 。

重点:对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,这个两个字段在提供方系统里面做联合唯一索引,这样当第三方调用时,先在本方系统里面查询一下,是否已经处理过,返回相应处理结果;没有处理过,进行相应处理,返回结果。注意,为了幂等友好,一定要先查询一下,是否处理过该笔业务,不查询直接插入业务系统,会报错,但实际已经处理了。

三、总结

幂等与你是不是分布式高并发还有JavaEE都没有关系。关键是你的操作是不是幂等的。一个幂等的操作典型如:把编号为5的记录的A字段设置为0这种操作不管执行多少次都是幂等的。一个非幂等的操作典型如:把编号为5的记录的A字段增加1这种操作显然就不是幂等的。要做到幂等性,从接口设计上来说不设计任何非幂等的操作即可。譬如说需求是:当用户点击赞同时,将答案的赞同数量+1。改为:当用户点击赞同时,确保答案赞同表中存在一条记录,用户、答案。赞同数量由答案赞同表统计出来。总之幂等性应该是合格程序员的一个基因,在设计系统时,是首要考虑的问题,尤其是在像支付宝,银行,互联网金融公司等涉及的都是钱的系统,既要高效,数据也要准确,所以不能出现多扣款,多打款等问题,这样会很难处理,用户体验也不好。

参考:

https://blog.csdn.net/jks456/article/details/71453053

https://www.cnblogs.com/linjiqin/p/9678022.html

相关文章

  • SpringBoot接口幂等性实现的4种方案!

    目录 什么是幂等性 什么是接口幂等性 为什么需要实现幂等性 引入幂等性后对系统的影响 Restful API 接口...

  • 什么是接口的幂等性,如何实现接口幂等性?一文搞定

    每天一个知识点 什么是接口的幂等性,如何实现接口幂等性? (一)幂等性概念 幂等性原本是数学上的概念,用在接口上就...

  • 接口幂等性

    接口幂等性 什么是接口幂等性? 最简单想到的实现接口幂等性(重复提交)的操作是什么? 最简单稍靠谱的解决方案是什么?

  • 接口幂等性书目录

    1.幂等性定义 1.1 数学定义 1.2 HTTP规范的定义 2. 何种接口提供幂等性 2.1 HTTP支持幂等性...

  • 接口的幂等性的N种考虑

    分布式服务接口的幂等性如何设计 什么是幂等性 一个分布式系统中的某个接口,要保证幂等性,该如何保证?这个事儿其实是...

  • 接口幂等性

    什么是接口幂等性? 幂等是数学和计算机学的概念,常见于抽象代数中,即f(f(x)) = f(x)。简单来讲就是接口...

  • 接口幂等性

    学习缘由 幂等性这个词很高大上,但是又不明白其中含义,因此查资料进行理解学习。参考原文:路人甲java 什么是幂等...

  • 接口幂等性

    一、概念 当微服务之间调用时服务A向服务B重复发送消息或者用户多次点击导致重复操作数据库。 例如支付订单接口,如果...

  • 接口幂等性

    含义:接口可重复调用后,在调用方多次调用的情况下,接口最终得到的结果是一致的。 有些接口天然具备幂等性,如查询接口...

  • 接口幂等性

    描述 幂等性是指一次操作和多次操作产生的结果一致。操作后的结果有三种状态,成功、失败、超时。在超时重试时就需要该操...

网友评论

      本文标题:接口幂等性

      本文链接:https://www.haomeiwen.com/subject/benxkctx.html