幂等 (idempotence) 的概念

article/2025/9/25 10:22:50

幂等 (idempotence) 的概念

幂等的数学概念

幂等是源于一种数学概念。其主要有两个定义

如果在一元运算中,x 为某集合中的任意数,如果满足 f(x) = f(f(x)) ,那么该 f 运算具有幂等性,比如绝对值运算 abs(a) = abs(abs(a)) 就是幂等性函数。

如果在二元运算中,x 为某集合中的任意数,如果满足 f(x,x) = x,前提是 f 运算的两个参数均为 x,那么我们称 f 运算也有幂等性,比如求大值函数 max(x,x) = x 就是幂等性函数。

幂等性在开发中的概念

在数学中幂等的概念或许比较抽象,但是在开发中幂等性是极为重要的。简单来说,对于同一个系统,在同样条件下,一次请求和重复多次请求对资源的影响是一致的,就称该操作为幂等的。比如说如果有一个接口是幂等的,当传入相同条件时,其效果必须是相同的。

特别是对于现在分布式系统下的 RPC 或者 Restful 接口互相调用的情况下,很容易出现由于网络错误等等各种原因导致调用的时候出现异常而需要重试,这时候就必须保证接口的幂等性,否则重试的结果将与第一次调用的结果不同,如果有个接口的调用链 A->B->C->D->E,在 D->E 这一步发生异常重试后返回了错误的结果,A,B,C也会受到影响,这将会是灾难性的。

在生活中常见的一些要求幂等性的例子:

  1. 博客系统同一个用户对同一个文章点赞,即使这人单身30年手速疯狂按点赞,那么实际上也只能给这个文章 +1 赞
  2. 在微信支付的时候,一笔订单应当只能扣一次钱,那么无论是网络问题或者bug等而重新付款,都只应该扣一次钱

幂等性与并发安全

在查阅网络资料的时候,我看到许多文章把幂等性和并发安全的问题有些混淆了。幂等性是系统接口对外的一种承诺,而不是实现,承诺多次相同的操作的结果都会是一样的。而并发安全问题是当多个线程同时对同一个资源操作时,由于操作顺序等原因导致结果不正确。

这两个实际上是完全独立的两个问题,比如说同一笔订单即使你不停的提交支付,如果扣除了多次钱,就说明该操作不幂等。而有多笔订单同时进行支付,最后扣除金额不是这多笔金额的总和,那么说明该操作有并发安全问题。所以幂等性和并发安全是完全两个维度的问题,要分开讨论解决。

我在一些讨论幂等性的文章中看到中给出的解决方案为‘悲观锁’和‘乐观锁’,这两个方案可以很好的解决并发问题,但是却不应该是幂等性问题的解决方案,特别是悲观锁是用于防止多个线程同时修改一个资源的。倒是乐观锁的版本号机制可以勉强以 token 或者状态标识 作为版本号来实现幂等性(下文解释token状态标识),勉强说的过去。

所以说幂等性与并发安全是不同的,在本文就只讨论幂等性的问题,对于并发安全问题不做讨论

Http 协议与幂等性

如果把操作按照功能分类,那就是增删改查四种,在 http 协议中则表现为 Get、Post、Put、Delete 四种。

查询操作 (Get)

Get 方法用于获取资源,不应当对系统资源进行改变,所以是幂等的。注意这里的幂等提现在对系统资源的改变,而不是返回数据的结果,即使返回结果不相同但是该操作本身没有副作用,所以幂等。

删除操作 (Delete)

Delete 方法用于删除资源,虽然改变了系统资源,但是第一次和第N次删除操作对系统的作用是相同的,所以是幂等的。比如要删除一个 id 为 1234 的资源,可能第一次调用时会删除,而后面所有调用的时候由于系统中已经没有这个 id 的资源了,但是第一次操作和后面的操作对系统的作用是相同的,所以这也是幂等的,调用者可以多次调用这个接口不必担心错误。

修改操作 (Put)

修改操作有可能是幂等的也可能不幂等。如果修改的资源为固定的,比如说把账户中金额改为 1000 元,无论调用几次都是幂等的。假如资源不固定,比如账户中金额减少50元,调用一次和调用多次的结果肯定不一样,这时候就不幂等了。在修改操作中想要幂等在下文中讨论。

2019-08-13 修改

原文对Put协议定义有错误,Put操作必须为幂等的,即如果声明为Put协议时就相当于对外声明这个接口是幂等的。所以对于原文举例说账户中金额减少50元这种操作在Put协议中是不允许的,只能做类似于账户中金额改为 1000 元的操作

参考:https://restfulapi.net/idempotent-rest-apis/

新增操作 (Post)

Post 新增操作天生就不是一个幂等操作,其在 http 协议的定义如下:

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

(https://www.w3.org/Protocols/...)

在其定义中表明了 Post 请求用于创建新的资源,这意味着每次调用都会在系统中产生新的资源,所以该操作注定不是幂等操作。这时候想要幂等就必须在业务中实现,方案在下文会讨论。

实现幂等性的方案

在上面提到的幂等性还是比较理论,下面结合一些常见的实际业务场景来讨论幂等性设计方案。

去重表

利用数据库的特性来实现幂等。通常是在表上构建一个唯一索引,那么只要某一个数据构建完毕,后面再次操作也无法成功写入。

常见的业务就是博客系统点赞功能,一个用户对一个博文点赞后,就把用户 id 与 博文 id 绑定,后续该用户点赞同一个博文就无法插入了。或是在金融系统中,给用户创建金融账户,一个用户肯定不能有多个账户,就在账户表中增加唯一索引来存储用户 id,这样即使重复操作用户也只能拥有一个账户。

状态标识

状态标识是很常见的幂等设计方式,主要思路就是通过状态标识的变更,保证业务中每个流程只会在对应的状态下执行,如果标识已经进入下一个状态,这时候来了上一个状态的操作就不允许变更状态,保证了业务的幂等性。

状态标识经常用在业务流程较长,修改数据较多的场景里。最经典的例子就是订单系统,假如一个订单要经历 创建订单 -> 订单支付取消 -> 账户计算 -> 通知商户 这四个步骤。那么就有可能一笔订单支付完成后去账户里扣除对应的余额,消耗对应的优惠卷。但是由于网络等原因返回了错误信息,这时候就会重试再次去进行账户计算步骤造成数据错误。

所以为了保证整个订单流程的幂等性,可以在订单信息中增加一个状态标识,一旦完成了一个步骤就修改对应的状态标识。比如订单支付成功后,就把订单标识为修改为支付成功,现在再次调用订单支付或者取消接口,会先判断订单状态标识,如果是已经支付过或者取消订单,就不会再次支付了。

Token 机制

Token 机制应该是适用范围最广泛的一种幂等设计方案了,具体实现方式也很多样化。但是核心思想就是每次操作都生成一个唯一 Token 凭证,服务器通过这个唯一凭证保证同样的操作不会被执行两次。这个 Token 除了字面形式上的唯一字符串,也可以是多个标志的组合(比如上面提到的状态标志),甚至可以是时间段标识等等。

举个例子,在论坛中发布一个新帖子,这是一个典型的 Post 新增操作,要怎样防止用户多次点击提交导致产生多个同样的帖子呢。可以让用户提交的时候带一个唯一 Token,服务器只要判断该 Token 存在了就不允许提交,便能保证幂等性。

上面这个例子比较容易理解,但是业务比较简单。由于 Token 机制适用较广,所以其设计中要注意的要求也会根据业务不同而不同。

Token 在何时生成,怎么生成?这是该机制的核心,就拿上面论坛系统来说,如果你在用户提交帖子的时候才生成 Token,那用户每次点提交都会生成新的 Token 然后都能提交成功,就不是幂等的了。必须在用户提交内容之前,比如进入编辑页面的时候生成 Token,用户在提交的时候内容带着 Token 一起提交,对于同一个页面无论用户提交多少次,就至多能成功一次。所以 Token 生成的时机必须保证能够使该操作具多次执行都是相同的效果才行。使用 Token 机制就要求开发者对业务流程有较好的理解。

结语

幂等性是开发当中很常见也很重要的一个需求。尤其是金融、支付等行业对其要求更加严格,既要有好的性能也要有严格的幂等性。除了对其概念的掌握,理解自身业务需求更是实现幂等功能的要点,必须处理好每一个结点细节,一旦某个地方没有设计完善,最后的结果可能仍旧达不到要求。


http://chatgpt.dhexx.cn/article/88brU8S8.shtml

相关文章

偏度

偏度公式如下: 现在想解决如何从图像上解决为正为负的问题,如图所示: 个人理解:偏度中的偏是针对变量相对于中心点(期望值)距离的一种描述;如果厚尾的话,就说明有很多点距离中心点比…

偏度(skewness)

偏度 偏度(skewness),是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。定义上偏度是样本的三阶标准化矩。 偏度定义中包括正态分布(偏度0) 算术平均值 中位数 众数,…

策略梯度

Policy Gradient Methods for Reinforcement Learning with Function Approximation(PG) 在强化学习的算法中存在两种算法,一个是基于价值函数的算法,另一个是基于策略梯度的算法。为什么要提出策略梯度算法呢? 基于策略的学习可能会具有更好…

推荐系统中的偏差

推荐系统消偏 推荐系统中的偏差IPW ——逆概率加权DICE ——区分兴趣和偏差建模因果推断 推荐系统中的偏差 预估问题 我们一般会注重两种误差,偏差和方差, 方差与模型泛化能力有关:通常关注模型的复杂度与是否过拟合;偏差则表现为…

特征偏度和异常值处理

(一)机器学习基础 - 偏度、正态化以及 Box-Cox 变换 https://my.oschina.net/mathinside/blog/4942126 对于数据挖掘、机器学习中的很多算法,往往会假设变量服从正态分布。例如,在许多统计技术中,假定误差是正态分布…

推荐系统去偏(Debiased Recommendation)研究进展概述

©作者 | 张景森 学校 | 中国人民大学信息学院硕士 文章来源 | RUC AI Box 引言 推荐系统作为解决信息过载的一种重要手段,已经在不同的应用场景下取得了不错的效果。近些年来关于推荐系统的研究主要集中在如何设计更好的模型来适应用户行为数据,进而…

【综述】推荐系统偏差问题 去偏最新研究进展(Bias and Debias in Recommender System)

文章目录 1. 推荐系统的反馈回路1.1 User -> Data1.2 Data -> Model1.3 Model -> User 2. 推荐系统中的Bias2.1 数据偏差(data bias)2.1.1 选择偏差(Selection Bias)2.1.2 曝光偏差(Exposure Bias)2.1.3 一致性偏差(Conformity Bias)2.1.4 位置偏差(Position Bias) 2.…

数据偏度介绍和处理方法

偏度(skewness)是用来衡量概率分布或数据集中不对称程度的统计量。它描述了数据分布的尾部(tail)在平均值的哪一侧更重或更长。偏度可以帮助我们了解数据的偏斜性质,即数据相对于平均值的分布情况。 有时,正…

【期权系列】基于偏度指数的择时分析

【期权衍生指标系列】基于偏度指数的择时分析 本篇文章是基于研究报告的复现作品,旨在记录个人的学习过程和复现过程中的一些思路。 感谢中信期货研究员前辈的宝贵思路。 一、偏度指数 1.偏度指数简介 偏度是描述数据分布形态的统计量,其描述的是统…

对于偏度的理解

偏度公式如下: 现在想解决如何从图像上解决为正为负的问题,如图所示:? 个人理解:偏度中的偏是针对变量相对于中心点(期望值)距离的一种描述;如果厚尾的话,就说明有很多点…

量化策略研究:股票中的偏度效应

2022年4月份以来,加密货币市场的暴跌强调了市场中性策略的重要性;基于此,有部分Quanter提出了基于加密货币的偏度策略:“Skewness/Lottery Trading Strategy in Cryptocurrencies”。 为此,小编不禁好奇:偏…

Maven安装和配置(详细版)

Maven安装和配置 Maven安装1、安装链接:2、配置环境变量: Maven配置1、修改Maven仓库下载镜像及修改仓库位置:2、在Idea上配置Maven: 测试Maven安装能否安装jar包 Maven安装 1、安装链接: Maven – Download Apache …

Maven 安装/学习入门详解!

Maven安装: Maven 软件的下载 为了使用 Maven 管理工具,我们首先要到官网去下载它的安装软件。通过百度搜索“Maven 点击 Download 链接,就可以直接进入到 Maven 软件的下载页面: 我们当时使用的是 apache-maven-3.5.2 版本&a…

Maven安装(超详解)

2.4.1 下载 下载地址:Maven – Download Apache Maven 在提供的资料中,已经提供了下载好的安装包。如下 : 2.4.2 安装步骤 Maven安装配置步骤: 解压安装 配置仓库 配置Maven环境变量 1、解压 apache-maven-3.6.1-bin.zip&a…

Maven安装教程详解

一、准备工作 1、确定电脑上已经成功安装jdk7.0以上版本 2、win10操作系统 3、maven安装包 下载地址:http://maven.apache.org/download.cgi 二、解压Maven安装包 在上述地址中下载最新的Maven版本,解压到指定目录(此处根据自己的…

Maven安装及配置(附带安装包)

Maven安装及配置 目录 Maven安装及配置 一: 安装包准备: 二: 安装配置 三: Maven 依赖地址更改为阿里镜像 四: idea中配置maven 一: 安装包准备: apache-maven-3.6.3-bin 链接&#xff1…

Maven安装和使用(详细版)

目录 演示版本: 安装 1.下载和解压 2.安装配置 IDEA使用Maven 1.IDEA配置Maven环境 2.新建maven项目 演示版本: maven:apache-maven-3.6.1 IEDA:2021.3 Windows:11 安装 1.下载和解压 1.下载去maven官网下载…

Maven安装与环境配置(Windows)

注意:Maven3以上版本要求安装jdk1.7以上版本。1、下载安装包 在Maven官网下载最新版的安装包:http://maven.apache.org/download.cgi 2、解压安装包 3、配置Maven环境变量 配置M2_HOME环境变量,指向maven的安装目录,并将bin目…

maven安装jar包

解决问题 主要解决开发过程中jar包依赖无法通过中央仓库、阿里云仓库等地方直接下载或者说对应的仓库中没有对应的jar包,比如 java-1.0.2.jar 这个jar包,很难从maven中央仓库中下载。这个时候我们就需要把对应的jar包给copy到本地,然后通过m…

Maven安装和配置(超详细+配置idea)

一、Maven安装准备 1、maven下载 1.1、百度网盘链接下载 链接:https://pan.baidu.com/s/1fGDRnWCfN3mrDM9oV5y01g?pwd1234 提取码:1234 1.2、maven官网下载 链接:maven官网下载 二、maven安装步骤 2、解压安装 解压…