首页 > 其他分享 >项目实战:并发下保证接口的幂等性

项目实战:并发下保证接口的幂等性

时间:2022-11-20 19:48:29浏览次数:51  
标签:实战 1.5 重复 接口 并发 version table 数据 id

图片

1.1 幂等性的概念

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

  • 多次请求一个资源时,应该有相同的结果(网络超时等问题除外)。 也就是说,一次请求被多次重复执行对资源自身的影响与第一次执行的影响相同。
  • 例如:用户查询结果多次扣款。 流水记录变成两个就是没有保证接口的幂等性。图片

1.2 防重设计和幂等设计

  • 防重设计和幂等设计在很多情况下是可以通用的,解决方案也比较类似,区别在于:
    • 防重设计:避免产生重复数据,对返回结果没有限制。
    • 幂等设计:避免产生重复数据,要求每次请求都返回同样的结果。

1.3 常见场景

  • FORM 表单,按钮重复点击,产生 ID 不一样的两条重复数据。
  • 浏览器页面返回按钮,此时数据依然存在,重复提交。
  • 接口重试机制(超时问题),重试过程中会产生重复数据。
  • 微服务调用,网络导致请求失败,feign 触发重复机制。
  • MQ 同一条消息重复读取。

1.4 汇总分析(数据库的角度

  • select 语句在数据不变的情况下,多次查询的结果相同,天然幂等操作。
  • insert 语句重复提交的情况下,会产生数据的重复。
  • delete 语句一次或者多次结果都是删除数据(已删除的数据不存在,返回0。 已删除的数据有多个,结果有多个。 删除操作也有乘方等属性)。
  • update 语句在大多数场景中的结果相同,但增量修改需要乘方等保证。例如表中存在 version 字段,此时更新时不是幂等。

1.5 保障幂等方式

1.5.1 唯一性索引

alter table xxx add UNIQUE KEY (key);
  • 异常精准捕获,以便返回数据。
  • DuplicateKeyException 异常。
  • MySQLIntegrityConstraintViolationException 异常。

1.5.2 单独表:防重复

  • 核心:防重表和业务表必须在同一个事务中。
  • 和唯一性索引的主要区别在于,并非所有的场景都不允许产生重复的数据。例如逻辑删除。

1.5.3 status 机制

  • 根据影响行数来判断是否更新成功。
update table set status = 1 where id = 1 and status=2;

1.5.4 数据库悲观锁

select * from table id = 1;
select * from table id = 1 for update;
  • 首先执行一遍查询,如果此时不满足条件,就直接返回了,无需锁住单条数据。
  • 悲观锁之后,再进行逻辑判断。
  • 执行业务操作。
  • 备注:mysql 存储引擎选用 innodb ,悲观锁字段最好是主键或唯一索引,不然可能会锁表。

1.5.5 数据库乐观锁(version )

图片

select id,version,amount from table id = 1;
-- version 查询结果为 0
update table set amount = amount + 1,version = version + 1 
where id=1 and version = 0;
  • 根据sql的执行结果影响行数判断是否执行成功。

1.5.6 token机制

  1. 生成全局唯一的 token,token 放到 redis 中(注意设置过期时间),页面跳转时获取 token 。
  2. 请求时携带token ,执行提交逻辑。
    图片

1.5.7 分布式锁

  • 通过 setNx、set 命令或者 Redission 第三方的框架。
    图片

1.6 小结

  • 幂等不仅对一次(或多次)请求没有副作用,对资源也没有副作用。 例如,select 对数据库不会产生任何影响,因为没有被insert、update、delete。
  • 网络超时等问题不在幂等讨论范围内。
  • 幂等性是系统服务对外约定而不是实现的,约定如果接口调用成功,则外部多次调用对系统的影响是一致的。 声明为幂等的服务,认为外部调用失败是常态,失败后一定会有重试。
    更多精彩欢迎关注微信公众号《格子衫007》!

图片

标签:实战,1.5,重复,接口,并发,version,table,数据,id
From: https://www.cnblogs.com/gezishan007/p/16909251.html

相关文章

  • 并发编程理论和进程理论
    目录一、并发编程理论操作系统发展史1、手工操作——穿孔卡片2、批处理——磁带存储1.联机批处理系统2.脱机批处理系统二、多道程序设计技术单道技术多道技术多道技术......
  • 并发编程 2 进程
    同步与异步#用来表达任务的提交方式同步:提交完任务之后原地等待任务的返回结果,期间不做任何事异步:提交完任务之后不愿地等待任务的返回结果,直接去做其他事,有......
  • 如何接入下游服务接口?
    S:当我们接到一个产品需求时,需要调用下游服务方提供的接口,比如调用下游LBS服务召回附近的商家,这时候需要拉着下游RD做技术方案评审,确定下游提供的接口是否满足PRD需求......
  • JAVA接口
    JDK1.8之前接口是接口,类是类。它们是同一层次的概念。接口中没有构造器。接口如何声明:interface在JDK1.8之前,接口中只有两部分内容,(1)常量:固定修饰符:publicstaticfina......
  • Rust实战系列-生命周期、所有权和借用
    本文是《Rustinaction》学习总结系列的第四部分,更多内容请看已发布文章:一、Rust实战系列-Rust介绍二、Rust实战系列-基本语法三、Rust实战系列-复合数据类型“理解......
  • Rust实战系列-深入理解数据
    本文是《Rustinaction》学习总结系列的第五部分,更多内容请看已发布文章:一、Rust实战系列-Rust介绍二、Rust实战系列-基本语法三、Rust实战系列-复合数据类型四、Rust......
  • JDK源码分析实战系列-PriorityQueue
    完全二叉树一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则......
  • 常用硬件接口知识
    VGA接口VGA(VideoGraphicsArray)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排......
  • 强化学习代码实战-09 SAC 算法
    离线学习算法:A3C,PPO,TRPO在线学习算法:DDPG,训练不稳定,容易陷入局部最优SAC:离线策略,随机策略,最大化累积奖励的同时最大化策略的熵(更好地探索环境,熵值越高,策略越随机,目......
  • 《ASP.NET Core技术内幕与项目实战》精简集-EFCore2.9:泛型仓储实现IRepository
    本节内容,部分为补充内容,部分涉及到5.2(P131-133)。主要NuGet包:如前章节所述 仓储模式,将数据访问层抽象出来,隐藏了底层对数据源的CRUD操作,这样在应用层或控制器中,我们直接......