什么是幂等性?四种接口幂等性方案详解

article/2025/10/3 17:45:45

幂等性在我们的工作中无处不在,无论是支付场景还是下订单等核心场景都会涉及,也是分布式系统最常遇见的问题,除此之外,也是大厂面试的重灾区。

知道了幂等性的重要性,下面我就详细介绍幂等性以及具体的解决方案,希望对大家有所帮助

什么是幂等性

幂等是一个数学和计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。

所谓接口幂等性,就是一次请求和多次请求某一个资源对于资源本身应该具有同样的结果

 为什么需要幂等性

业务开发中,经常会遇到重复提交的情况,无论是由于网络问题无法收到请求结果而重新发起请求,或是前端的操作抖动而造成重复提交的情况。

在交易系统,支付系统这种重复提交造成的问题尤其明显,比如:用户在APP上连续点击了多次提交订单,后台应该只产生一个订单

再比如:向支付宝发起支付请求,由于网络问题或系统BUG重试,支付宝应该只扣一次钱,而不是多次重试就多次扣钱

再比如:现在是微服务时代了,服务接口在外部调用者会存在多次调用的情况(考虑网络中断重试等),为了防止外部多次调用对系统数据状态的发生多次改变,将服务接口设计成幂等,就是为了防止多次重试造成系统不一致的问题

通过以上典型的支付场景就知道了幂等性的重要性,那么问题来了,如何实现幂等性,有哪些解决方案?接下来我们聊聊

幂等性的解决方案 

1. 数据库唯一主键 / 数据库唯一索引

数据库唯一主键的实现主要是利用数据库中主键唯一约束的特性,一般来说唯一主键比较适用于“插入”时的幂等性,其能保证一张表中只能存在一条带该唯一主键的记录。

数据库唯一索引可以避免脏数据的产生,当插入重复数据时数据库会抛出异常,依次保证数据的唯一性

唯一索引的创建示例如下

 使用数据库唯一主键完成幂等性时需要注意的是,该主键一般来说并不是使用数据库的自增主键,而是使用分布式全局ID来做主键,这样才能保证在分布式环境下ID的全局唯一性。

总结:适用以下操作

    插入操作

    删除操作

2. 数据库乐观锁

数据库乐观锁方案一般只能适用于执行“更新操作”的过程,我们可以提前在对应的数据表中多添加一个字段,作为当前数据的的版本标识。

这样每次对这条数据执行更新时,都会将该版本标识作为一个条件,值需要为上次待更新数据中的版本标识的值。

select version from tablename where xxx

更新数据时首先和版本号做对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败

update tablename set count=count+1, version=version+1 where version=#{version}

总结:适用以下操作

    更新操作

3. PRG模式

Post/Redirect/Get是一种web开发设计模式,用于防止表单的重复提交

默认情况,提交Post请求到服务器后,如果直接刷新浏览器,会重新再提交一次Post请求

 

 在访问电商网站时,提交订单采用的是Post请求,如果直接刷新浏览器就容易导致重复订单的提交,这个不是用户希望发生的行为。

PRG方法就是防止这种情况的发生,下面例图描述了用PRG方法来避免Post请求的重复提交。当服务器处理完Post请求后,会发响应给用户浏览器,指示用户浏览器用Get方式立刻访问另一条URL。用户浏览器拿到Get请求的数据,整个流程才算结束。

 

 由于已经是新的页面了,此时用户再刷新当前页面,就不会引起Post请求的重复提交

4. 防重Token令牌

针对客户端连续点击或者调用方的超时重试等情况,例如提交订单,此种情况可以用Token的机制实现防止重复提交。

简单的说就是前端在调用接口的时候先向后端请求一个全局ID(Token),后面请求的时候带上这个全局ID(Token最好放在Headers中),后端需要对这个Token作为Key,用户信息作为Value到Redis中进行键值内容校验,如果Key存在且Value值和Token值一致就执行删除命令,然后正常执行后面的业务逻辑。

 如果不存在对应的Key或Value不匹配,就返回重复执行的错误信息,这样来保证幂等性

上面我只是列举了解决幂等性的解决方案与思路,其实还有很多类似解决方案,比如订单流程还可以结合前端拦截,以及更多的后端方案来保障唯一性。

这些还需要结合你的实际业务场景,来最终选择更适合你的解决方案。但万变不离其宗,都是为了保证一次操作,保证唯一约束,这才是幂等性的本质。


http://chatgpt.dhexx.cn/article/F0h6EDZM.shtml

相关文章

接口的幂等性

1、接口调用存在的问题 现如今我们的系统大多拆分为分布式 SOA,或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用 RPC 通信或者 restful。既然是通信,…

如何保证接口的幂等性?

什么是幂等性?所谓幂等,就是任意多次执行所产生的影响均与一次执行的影响相同。 为什么会产生接口幂等性问题 在计算机应用中,可能遇到网络抖动,临时故障,或者服务调用失败,尤其是分布式系统中,接口调用…

什么是接口的幂等性以及如何实现接口幂等性

目录 1、接口调用存在的问题 2、什么是接口的幂等性 3、不做接口的幂等性会产生什么影响 4、什么情况下需要保证接口的幂等性 4.1 select:查询操作 4.2 insert:新增操作 4.3 delete:删除操作 4.3.1 绝对删除 具有幂等性 4.3.2 相对删…

Python安装pygame教程

Python安装pygame教程 1、版本说明 由于python3.8与pygame存在不兼容的问题,因此在下载Python的时候,需要下载python3.8以下版本的,我下载的是python3.7.5 2、具体步骤 1、在本机控制台通过命令安装pygame pip install pygame 出现错误 …

Pygame 教程(2):重要的概念及对象

本章,将介绍 Pygame 中的重要概念及对象。 导航 上一章:创建第一个应用程序 下一章:绘制图形 文章目录 导航像素坐标Rect 对象Color 对象Surface 对象实例:矩形生成器创建初始窗口创建生成矩形的函数调用函数完整代码 结语 像素…

Pygame教程系列二:MoviePy视频播放篇

【前言】 在pygame 2.0.0版本之前,播放视频可以使用pygame.movie.Movie(xxxx.mpg)播放(只支持.mpg格式的视频),但是在pygame 2.0.0之后,作者因为觉得视频模块维护成本太高就给抛弃了,假如你使用pygame 2.0.0,还调用上述…

Pygame 教程(4):图像传输和绘制文本

本章,你将学会如何传输图像和绘制文本。 导航 上一章:绘制图形 下一章:监测游戏时间 文章目录 导航加载图像导出图像绘制文本实例:画板添加常量限制坐标定义属性绘制色板更改线条粗细处理鼠标事件处理键盘事件调用事件处理方法完…

Pygame基础教程(一)

写在前面的话: 本系列教程仅有一些在本机调试通过的代码(如代码中发现bug,恳请包涵)。除代码中出现的一些主要注释外,不会出现太多其他文字解释,但是,文章中会给出主要模块的官方文档地址。再次…

Pygame 教程(5):监测游戏时间

本章,你将学习如何监测游戏时间。 导航 上一章:图像传输和绘制文本 下一章:努力更新中…… 文章目录 导航监测时间游戏帧速率实例:绘图性能对比结语 监测时间 在游戏程序中,时常需要随着时间的流逝而做出不同的动作…

Pygame教程系列四:播放音频篇

【前言】 pygame播放音频文件这部分相对来说比较简单,主要是用到pygame.mixer模块,不过也有一些地方需要注意的,咱们直接先看看案例 1、案例效果图 2、案例代码 import pygame from mutagen.mp3 import MP3 # 标识是否退出循环 exitFlag Fa…

python3.8安装pygame_Python3.8安装Pygame教程

注:因为最近想用一下Python做一些简单小游戏的开发作为项目练手之用,而Pygame模块里面提供了大量的有用的方法和属性。今天我们就在之前安装过PyCharm的基础上,安装Pygame,下面是安装的步骤,希望能够帮到大家。 第一步…

Pygame 教程(3):绘制图形

本章,你将学习如何在 Pygame 中绘制图形。 导航 上一章:重要的概念及对象 下一章:图像传输和绘制文本 文章目录 导航抗锯齿draw 模块实例:跟随鼠标的图形创建初始窗口添加变量捕捉鼠标事件绘制图形完整代码 结语 抗锯齿 抗锯齿…

Mac Pycharm导入Pygame教程(超细)

首先先新建一个想要使用Pygame的项目 进入项目后,点击文件(File)——新项目设置(settings) 点击新项目的偏好设置(Preferences for new project ) 随后可以看到 点击Python 编译器&#xff0…

mac python3.8上怎么安装pygame 第三方库_Python3.8安装Pygame教程步骤详解

注:因为最近想用一下python做一些简单小游戏的开发作为项目练手之用,而Pygame模块里面提供了大量的有用的方法和属性。今天我们就在之前安装过PyCharm的基础上,安装Pygame,下面是安装的步骤,希望能够帮到大家。 第一步 安装Python和pip 如果已安装,使用python --version …

Pygame教程系列一:快速入门篇

【简介】 Pygame 是python用来开发视频游戏的游戏引擎,底层主要是SDL库实现,算是目前利用python开发小游戏的一个性能比较高的一个游戏框架 一、安装pygame 使用pip下载安装 pip install pygame二、入门案例详析 1、示例效果 2、示例代码 import os …

pygame教程3

目录 做个小游戏精灵类精灵类介绍使用精灵类 做个小游戏 这个小游戏使用了pygame教程2的知识。 #↓初始化 import pygame,sys from pygame.locals import * pygame.init()#初始化pygame。 screen pygame.display.set_mode((800,600)) pygame.display.set_caption("Hell…

pygame教程2

目录 响应键盘上的事件让画面动起来了解x轴和y轴画圆形圆形动起来 响应键盘上的事件 import pygame#导入pygame。 import sys#导入sys from pygame.locals import *#导入pygame所有的常量,方便以后使用。 pygame.init()#初始化pygame。 screen pygame.display.set…

pygame教程笔记

pygame教程 安装pygameGame Development 1-1: Getting Started with PygameGame Development 1-2: Working with SpritesGame Development 1-3: More About SpritesPygame Shmup Part 1: Player Sprite and ControlsPygame Shmup Part 2: Enemy SpritesPygame Shmup Part 3: Co…

pygame基础教程

pygame简介 pygame可以实现python游戏的一个基础包。 pygame实现窗口 初始化pygame,init()类似于java类的初始化方法,用于pygame初始化。 pygame.init() 设置屏幕,(500,400)设置屏幕初始大小为500 * 400的大小, 0和32 是比较高…

Python pygame(GUI编程)模块最完整教程(1)

提示:下滑文章左侧可以查看目录!本教程分为多篇,总目录如下。 总目录: README.md Python-ZZY/Python-Pygame最完整教程 - Gitee.com 1 初识pygame 1.1 简介 pygame是python中一个流行的GUI编程模块,是专门为了开发游…