作者 l 会点代码的大叔(CodeDaShu)

在单体架构时代,就存在着接口幂等性的问题,只不过到了分布式、高并发的场景之后,接口幂等性的问题会更加明显。

01

幂等性的概念

那么什么是幂等性呢?

当用户对同一操作请求了一次或者多次,最终的结果是一致的,并不会因为多次请求产生副作用;比如同一个订单支付了两次,最后应该只扣客户一次钱。

查询和删除:查询具有天然的幂等性,在数据不变的前提下,相同查询条件查询一次和查询多次的结果都是一样的;删除也一样,相同的条件删除一次和删除多次,可能删除的数据量不一样,但是数据库中的数据不会因为执行了多次删除而不同。

新增和修改:如果不做幂等性处理,可能就会产生问题;执行多次新增操作,可能会导致一模一样的数据产生了多条(主键自动生成);修改操作,如果只是把某些字段更新成固定的值,不会有幂等性问题,但是如果新值要在旧值上做处理做计算,如增加多少、减少多少,那么多次执行的结果就会有差异。

那么为了保证接口的幂等性,有哪些方法呢?

02

保证幂等性的解决方案

1. 唯一索引

使用唯一索引,可以有效的防止新增脏数据:当表中存在唯一索引的时候,并发新增相同数据的时候就会报错,不过这在单库单表的时候才有效,如果项目数据量很大,采用了分库分表的策略,就不能再通过数据库的唯一性索引来解决幂等性的问题了。

2. 悲观锁

获取数据的时候加锁获取;

select * from table where col='xxx' for update;

这里要注意, where 条件中的字段必须是主键或者有索引,否则会锁全表。

3. 分布式锁

在业务系统执行插入或更新操作的时候,先要获取分布式锁,然后做操作,之后释放锁;分布式锁保证在一个时间内,只会有一个线程对数据进行操作。

4. 全局唯一 ID

每次请求,都生成一个全局的唯一 ID,接口调用的时候携带者这个 ID,而业务操作方在之执行前判断这个 ID 是否已经在本地存在,如果不存在,则执行交易后记录 ID(存到数据库或Redis中,表示该交易已经执行);如果已经存在,表示交易已经执行过了,不能再次执行。

许多分布式架构中,生成全局唯一 ID 都会被作为一个基础的微服务,当然这个服务的可靠性要求极高,或者可以使用全局唯一 ID 算法,由每个应用自己生成。不过总的来说,引入全局唯一 ID 这个方案,实现起来还是非常繁琐的。

5. 数据版本号

这个方案算是乐观锁的一种;在数据中增加版本号的概念,那么在做数据修改,把当前数据的版本号带上,修改的时候要按照版本号判断数据是否发生过更改。如果没有发生过更改,则执行业务操作,并更新版本号(这种方法适合在更新的场景中)。

下面的代码,意会一下:

updateDate(Object obj , int version);
update set obj , version+1 where ... and version = 入参version;

6. 业务状态

有些业务流程,每一步都是有状态的,比如网上购物可能会有:订单创建、付款、发货,那么付款之前保单状态为“待付款”,付款之后可以将保单的状态修改为“待发货”;那么如果发起重复扣款的话,第二次扣款的时候保单状态已经变化了,就会扣款失败。

7. 去重表

如果业务中有唯一性的标识时,可以使用去重表,把这个唯一性的表示保存到去重表中,如果重复插入,那么会被校验住。

比如上面的场景,一个订单只会付款一次,那么在付款的时候,把订单号作为唯一性的标识,保存到去重表中,可以保证付款操作只会发生一次;这个方法也用到了唯一 ID,不过和全局唯一 ID 不同,这个唯一 ID 是针对具体业务的。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

点一下按钮调两次接口?浅谈接口设计的幂等性相关推荐

  1. 计算机机房搬迁复杂吗,中心机房搬迁的两种方式浅谈

    中心机房搬迁的两种方式浅谈 最近在处理中心机房机房搬迁的事宜,很多事情其实看起来简单,但是实现的时候总会有一些不如意的地方,很可能你考虑的是一个看起来非常稳定完美的搬迁,但是 实现中总会有这样那样的限 ...

  2. 中鸣循迹机器人_浅谈机器人设计方法

    浅谈机器人设计方法 摘要: 机器人是人类完成智能化中非常重要的工具, 随着时代的发展, 机器 人已经在世界有了一定的发展,甚至很多国家机器人已经运用到实际的生活中 去. 而机器人的设计方法无疑是很多人 ...

  3. 计算机中用户的分类有哪些,用户分类浅谈交互设计 -电脑资料

    说到网络产品,离不开的话题就是用户,就像传统行业的消费者, 不分类不好定位, 好的用户分类让我知道了我在追求哪些人,满足哪些人,影响哪些人.但分不好类又会错位,更糟,那怎样才能对某一款产品的用户群进行 ...

  4. 浅谈数据库设计技巧(上)

    浅谈数据库设计技巧(上) 说到数据库,我认为不能不先谈数据结构.1996年,在我初入大学学习计算机编程时,当时的老师就告诉我们说:计算机程序=数据结构+算法.尽管现在的程序开发已由面向过程为主逐步过渡 ...

  5. 浅谈工厂设计--java必备技能

    浅谈工厂设计–java必备技能 说到工厂,我就联想到了亚洲的大工厂富士康–接过订单然后按照固定的模板生产商品,其实java中工厂类中的工厂方法也是一样,接过参数,根据参数来生产需要的商品: 今天我们一 ...

  6. 浅谈购物中心设计之外立面设计注意点

    购物中心的主体定位中,可以通过外立面设计充分的发挥和展现个性,吸引八方游客,从而使购物中心的商圈辐射超越了地区的界限.具体来说,购物中心外立面设计需要注意哪些方面呢?我们今天就来浅谈购物中心设计之外立 ...

  7. 脑机接口与量子计算机,关于脑机接口---浅谈人工智能。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 脑机接口,这个词语大家应该是很陌生的,这是我第一次发帖,和大家谈谈脑机接口,以及我正在努力的方向,我用容易理解的方式来谈,尽量不用术语.最后在说一下关于人 ...

  8. 浅谈----接口测试用例

    做测试写测试用例是基础嘛,那设计一个好的接口测试用例,能够帮助我们在执行时更好的发现缺陷,下面整理一份我自己对接口测试用例编写的一些思路 因为是对接口进行测试,那么对参数,也要重点测试下 <1& ...

  9. 我的家乡网页设计_Graphic Design|康石石浅谈LOGO设计在作品集中的创作方法

    写在前面的话 平面设计范畴极广,其领域不仅限于常见的版式设计.海报设计.LOGO设计.VI设计.书籍装帧.广告设计.网页设计.在艺术留学申请过程中,学习平面设计的同学们需依据目标院校对作品集项目及页数 ...

  10. 借用英雄联盟浅谈游戏设计

    我和我的团队这几周正在为某公司开发一款游戏,由于商业因素我在这里不能透露游戏相关信息,在这里浅谈一下游戏设计也可以说是游戏如何吸引玩家长时间玩.吸引玩家玩的时间越长意味着赚更多的钱.对的越多玩家,越长 ...

最新文章

  1. C语言的变量的内存分配
  2. python和c++的相互调用教程
  3. Android在xml中定义Shape
  4. ListView 与 ImageList
  5. python和c-Python与C的简单比较(Python3.0)
  6. 并发编程基础之volatile关键字的用法
  7. element 密码输入框用*显示_用 Java 实现天天酷跑,这个真的有点强了
  8. linux vi行尾总是显示颜色,【转载】Linux 下使用 vi 没有颜色的解决办法
  9. Python configparser模块操作代码实例
  10. 【5.0】对象生命周期及crud操作
  11. 同一个网络下怎样在两台机器之间传输文件
  12. C++——模板(超详细的模板解析)
  13. ftp中转服务器,bat实现的ftp中转
  14. Android 四大组件 -- service
  15. 【程序员读论文】LeCun, Y., Bengio, Y. Hinton, G. Deep learning. *Nature* **521,** 436–444 (2015).
  16. 微信小程序样式-id选择器的使用教程
  17. Vue开发需要的网站
  18. python创建空字典什么意思_Python3基础 dict 创建字典 空字典
  19. 重读Ardupilot中stabilize model+MAVLINK解包过程
  20. 新创公司如何建立优质的工程师到职流程

热门文章

  1. C语言中降序qsort通用写法
  2. notability怎么用_红茶丨如何用ipad提高你的西语学习效率
  3. CF438E The Child and Binary Tree(有意思的生成函数 + 多项式求逆 + 多项式开方)
  4. 归并排序以及三种常见优化
  5. 数据库基础笔记(MySQL)6 —— 基础事务
  6. html怎么一段时间把网页背景更换_汽车轮毂多少公里更换一次?受到磕碰必须更换吗?...
  7. java写出文本文档乱码_对象流如何写出到文件以及为什么乱码
  8. 将某表一行数据的某些字段插入到该表
  9. Spring Batch事务处理
  10. 爬虫--pyquery使用