实现接口幂等性的几种方案

抢微信红包的时候我们都知道:一个红包一旦你抢过之后,以后无论你点多少次都是一样的结果。红包会提示你已经抢过此红包,而不会让你再抢一次。

抢红包接口就是一个非常典型的幂等接口,抢一次和抢多次具有一样的效果。类似的接口在我们的开发过程中会有很多,比如在电商的下单过程中:

订单创建接口,第一次调用返回超时了,重试机制一般会再次调用这个接口,此时我们不能因为这个接口被调了两次就创建两个一样的订单;
库存扣减接口,支付接口也是类似的逻辑;

今天的文章就来讲讲什么是接口的幂等性,并介绍几种实现接口幂等性的方案。

什么是幂等

幂等原先是数学中的一个概念,表示进行1次变换和进行N次变换产生的效果相同。

当我们讨论接口的幂等性时一般是在说:以相同的请求调用这个接口一次和调用这个接口多次,对系统产生的影响是相同的。如果一个接口满足这个特性,那么我们就说这个
接口是一个幂等接口。比如上面的抢红包接口。

PS:这边顺带说下幂等和防止重复提交的区别。
防止重复提交更多的是不让用户发起多次一样的请求。比如说用户在线购物下单时点了提交订单按钮,但是由于网络原因响应很慢,此时用户比较心急多次点击了订单提交按钮。
这种情况下就可能会造成多次下单。一般防止重复提交的方案有:将订单按钮置灰,跳转到结果页等。主要还是从客户端的角度来解决这个问题。

幂等更多的是在重复请求已经发生,或是无法避免的情况下,采取一定的技术手段让这些重复请求不给系统带来副作用。

什么情况下需要幂等

并不是所有接口都需要保证幂等性。以相同的请求调用这个接口一次或多次,需要给调用方返回一致的结果时,就要考虑将这个接口设计成幂等接口。

实现幂等的几种方案

在我们设计幂等接口时重点关注新增接口和更新接口。因为查询和删除操作天生是幂等的(根据id查询和根据id删除多次对系统的影响是一致的),不需要我们提供额外的
技术手段来保证幂等性。(??)

对于新增和更新接口,大致有以下几种方案可以保证接口幂等性。

来源加序列号

这是一种比较好理解,通用的方案。

当调用接口时,参数中必须传入source字段和seq字段(这边举了一个我们项目中的列子,其实并不一定要传两个字段,传一个唯一的序列号uuid也能达到一样的效果)。服务端接收到请求,先判断自己是否是一个幂等接口,如果不是幂等接口就正常处理请求。

如果是一个幂等接口,就将sourceseq组成联合主键去数据库表中或者是Redis中查询,如果没有查询到,说明没处理过这个请求,然后正常处理请求就行了。处理完之后将处理结果和sourceseq信息一个存入数据库或Redis中。

如果根据sourceseq能查询到,说明已经处理过这个请求了,直接将处理的结果返回即可。

我们发现这种方案非常简单,而且易于理解,通用。但是如果请求量很大的话,存放请求记录的表会很大,这个时候可以将一段时间之前的记录删除,以提升性能。

唯一索引(唯一字段)

这种方案适合用于执行新增操作的接口。

比如说新增用户接口。我们将用户表中的身份证字段加上唯一索引。当同一个请求调用两次时,我们可以先根据身份证字段查询下用户是否存在,不存在的话再新增。存在的话就返回新增失败。
或者直接新增也行,数据库会抛异常,我们对异常处理返回前台就行了。

PS:大家可能会有一个疑问,我同一个请求调用两次,第一返回新增成功,第二次返回失败,返回的结果不同啊。这个接口还是幂等接口么?
这边我要重申下概念,幂等强调的是接口一次调用和多次调用产生的效果是一样的。这边调用一次和调用多次都是新增了一个对象,所以还是满足幂等的。

乐观锁

这种方案适用于执行更新操作的接口。

乐观锁只是在更新数据那一刻锁表,其他时间不锁表,所以相对于悲观锁,效率更高。 我们一般通过数据库来实现乐观锁,比较通用的做法是增加一个时间戳字段。

update table_xxx set name=#name#, timestamp = now where id=#id# and timestamp=#timestamp# --这个值由前端到数据中查询出来,再传过来

参考

(0)

相关推荐

  • 建设高并发系统的一些经验总结

    前言 离开饿了么有一段时间了,在饿了么期间从2017年开始接手运单系统的开发和维护工作,从最早的日均百万单,到离开时的日均千万单,业务的快速发展再加上外卖业务的特点是业务量集中在午高峰和晚高峰两个高峰 ...

  • java基础之反射类型Type

    java基础之反射类型TypeJava在加入泛型之后,仅仅Class已经不足以描述数据的类型了,比如List类型的数据,其Class的类型为List.class,但是其类型包含了泛型参数,所以java ...

  • 分布式事务最经典的七种解决方案!

    优质文章,第一时间送达 随着业务的快速发展.业务复杂度越来越高,几乎每个公司的系统都会从单体走向分布式,特别是转向微服务架构.随之而来就必然遇到分布式事务这个难题,这篇文章总结了分布式事务最经典的解决 ...

  • Spring Boot 实现接口幂等性的 4 种方案!还有谁不会?

    Java技术栈 476篇原创内容公众号作者:超级小豆丁链接:mydlq.club/article/94一.什么是幂等性幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会 ...

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

    来源:mydlq.club/article/94/一.什么是幂等性二.什么是接口幂等性三.为什么需要实现幂等性四.引入幂等性后对系统的影响五.Restful API 接口的幂等性六.如何实现幂等性方案 ...

  • 卧室梳妆台如何设计?试试这5种方案,1㎡让你做精致女人

    来源:阳台设计精选(ID:jia-120p) 爱美之心,人皆有之.对女人来说,卧室梳妆台是必不可少的.美好的一天,从梳妆打扮开始.那么,卧室梳妆台要如何设计呢? 床头梳妆台梳妆台直接设计在卧室床头,如 ...

  • 五种方案实现“零冷水”,让热水即用即来

    从事装修十多年来,发现不少业主对用水的需求越来越高,尤其对热水的"即用即来"有着很高的期待. 根据过往的施工经验和装修案例,秀巢网小编一共总结了五种实现"零冷水" ...

  • Spring Boot 解决跨域问题的 3 种方案!

    前后端分离大势所趋,跨域问题更是老生常谈,随便用标题去google或百度一下,能搜出一大片解决方案,那么为啥又要写一遍呢,不急往下看.Java面试宝典PDF完整版 问题背景: Same Origin ...

  • 对待死亡的三种方案

    死亡的哲学 解决这一问题有三种方案.最佳方案是,不想它,不管它.这是孔子的方案.关于死亡的哲学探讨总体来说是相当空泛的.没有价值的.这里,我推崇一位像孔子一样的大家――欧文·埃德曼:他不愿意思考死亡, ...

  • Excel多表汇总,两种方案,总有一款适合你!!

    今天来说点老生常谈的问题,多表数据汇总,比如我们一个Excel文件中,有5周的数据,我们需要来一张汇总表!怎么样快速搞定呢? 需求说明 数据说明:5周的数据,姓名没有顺序,可能多可能少! 需求说明:提 ...

  • 工厂常见计件工资的7种方案,供参考!

    标杆精益 前天 来源|CNC数控技术 全文总计1771字,需阅读5分钟,以下为正文: 计件工资是指按照合格产品的数量和预先规定的计件单位来计算的工资. 它不直接用劳动时间来计量劳动报酬,而是用一定时间 ...

  • 填EXCEL中计算分组占比天坑的三种方案

    函数实战系列-第八期,分组占比 开篇:excel计算百分比是非常简单的事情,分组占比也不是很难,之所以有坑,十之八九是自己给挖的 需求说明:按照城市计算销售占比 就需求本身而言,难度很小,但是有了天坑 ...