什么是幂等操作?
答案 0 :(得分:812)
在计算中,幂等操作是指如果使用相同的输入参数多次调用它,则不会产生额外的影响。例如,从集合中删除项目可以被视为对集合的幂等操作。
在数学中,幂等操作是 f(f(x))= f(x)的操作。例如,abs()
函数是幂等的,因为abs(abs(x)) = abs(x)
适用于所有x
。
这些稍微不同的定义可以通过考虑数学定义中的 x 表示对象的状态来协调,而 f 是可以改变该对象的操作。例如,请考虑Python set
及其discard
方法。 discard
方法从集合中删除元素,如果元素不存在则不执行任何操作。所以:
my_set.discard(x)
与两次执行相同操作的效果完全相同:
my_set.discard(x)
my_set.discard(x)
幂等操作通常用于网络协议的设计,其中执行操作的请求保证至少发生一次,但也可能不止一次发生。如果操作是幂等的,那么执行操作两次或多次都没有坏处。
有关详细信息,请参阅idempotence上的维基百科文章。
上述答案之前有一些不正确和误导性的例子。 2014年4月之前撰写的评论参考旧版本。
答案 1 :(得分:120)
幂等操作可以重复任意次数,结果与只执行一次相同。在算术中,向数字加零是幂等的。
在“RESTful”Web服务的上下文中对Idempotence进行了大量讨论。 REST旨在最大限度地利用HTTP来为程序提供对Web内容的访问,并且通常与基于SOAP的Web服务形成对比,后者只是在HTTP请求和响应中挖掘远程过程调用样式服务。
REST将Web应用程序组织到“资源”(如Twitter用户或Flickr图像)中,然后使用POST,PUT,GET和DELETE的HTTP谓词来创建,更新,读取和删除这些资源。
Idempotence在REST中扮演着重要角色。如果您获取REST资源的表示(例如,从Flickr获取jpeg图像),并且操作失败,您可以反复重复GET直到操作成功。对于Web服务,获取图像的次数无关紧要。同样,如果您使用RESTful Web服务更新您的Twitter帐户信息,您可以多次将新信息PUT,以便从Web服务获得确认。投入一千次与投入一次相同。类似地,删除REST资源一千次与删除一次相同。因此,幂等性使得构建能够抵御通信错误的Web服务变得更加容易。
进一步阅读:RESTful Web Services,Richardson和Ruby(幂等在第103-104页讨论)和Roy Fielding的PhD dissertation on REST。 Fielding是HTTP 1.1,RFC-2616的作者之一,它谈论了section 9.1.2中的幂等性。
答案 2 :(得分:89)
无论你多少次调用该操作,结果都是一样的。
答案 3 :(得分:43)
幂等性意味着应用一次操作或多次应用它会产生相同的效果。
示例:
对于纯函数(没有副作用的函数),则幂等性意味着f(x)= f(f(x))= f(f(f(x)))= f( f(f(f(x))))= ......对于x的所有值
对于具有副作用的功能,幂等性还意味着在第一次应用后不会产生额外的副作用。如果您愿意,可以将世界状态视为该函数的附加“隐藏”参数。
请注意,在您正在进行并发操作的世界中,您可能会发现您认为幂等的操作不再是这样(例如,另一个线程可能会取消上面示例中的布尔标志的值)。基本上每当你有并发性和可变状态时,你需要更加仔细地考虑幂等性。
幂等性通常是构建健壮系统的有用属性。例如,如果您可能收到来自第三方的重复消息,则将消息处理程序作为幂等操作有助于使消息效果仅发生一次。
答案 4 :(得分:22)
如果传入相同的参数,即使您多次调用,幂等操作也会以相同的状态生成结果。
答案 5 :(得分:13)
只是想抛弃一个展示幂等性的真实用例。在JavaScript中,假设您正在定义一组模型类(如在MVC模型中)。通常实现的方式在功能上等同于这样的(基本示例):
function model(name) {
function Model() {
this.name = name;
}
return Model;
}
然后你可以定义这样的新类:
var User = model('user');
var Article = model('article');
但是如果你试图通过User
从代码中的其他地方获取model('user')
类,那么它将会失败:
var User = model('user');
// ... then somewhere else in the code (in a different scope)
var User = model('user');
这两个User
构造函数会有所不同。也就是说,
model('user') !== model('user');
要使其幂等,您只需添加某种缓存机制,如下所示:
var collection = {};
function model(name) {
if (collection[name])
return collection[name];
function Model() {
this.name = name;
}
collection[name] = Model;
return Model;
}
通过添加缓存,每次执行model('user')
时它都是同一个对象,因此它是幂等的。所以:
model('user') === model('user');
答案 6 :(得分:8)
幂等操作是可以多次应用的操作,操作或请求,而不会更改结果,即系统状态,超出初始应用程序。
示例(WEB APP上下文):
NULLIPOTENT: 如果一个操作没有副作用,比如纯粹在网页上显示信息而数据库没有任何变化(换句话说你只是在读数据库),我们说操作是NULLIPOTENT。所有GET都应该是无效的。否则,请使用POST。
幂等: 电子邮件消息系统中的消息将打开并在数据库中标记为“已打开”。可以多次打开该消息,但这种重复操作只会导致该消息处于“打开”状态。这是一种幂等的操作。
NON-幂等: 如果操作总是导致状态发生变化,比如一遍又一遍地向用户发送相同的消息,导致每次都发送并存储在数据库中的新消息,我们说操作是非IDEMPOTENT。
在谈论系统状态时,我们显然忽略了希望无害和不可避免的影响,如记录和诊断。
答案 7 :(得分:7)
幂等操作:多次执行时没有副作用的操作。
示例:从数据资源中检索值并打印出来的操作
非幂等操作:如果多次执行会导致一些伤害的操作。 (因为他们改变了一些值或状态)
示例:退出银行帐户的操作
答案 8 :(得分:7)
相当详细和技术性的答案。只需添加一个简单的定义。
Idempotent = Re-runnable
例如,
如果多次执行,Create
操作本身并不能保证无错运行。
但如果有一个操作CreateOrUpdate
,那么它表示重新运行(Idempotency)。
答案 9 :(得分:6)
对一个集合进行幂等运算会在应用一次或多次时保持其成员不变。
它可以是像 absolute(x)这样的一元运算,其中x属于一组正整数。这里绝对(绝对(x))= x。
它可以是二进制操作,例如一个集合与其自身的联合将始终返回相同的集合。
欢呼声
答案 10 :(得分:5)
任何操作都是每第n个结果都会产生与第1个结果的值匹配的输出。例如,-1的绝对值是1.绝对值-1的绝对值是1.绝对值绝对值-1的绝对值是1.依此类推。
另请参阅:何时使用递归会非常愚蠢?
答案 11 :(得分:1)
了解幂等运算的一个很好的例子可能是用遥控钥匙锁定汽车。
log(Car.state) // unlocked
Remote.lock();
log(Car.state) // locked
Remote.lock();
Remote.lock();
Remote.lock();
log(Car.state) // locked
lock
是幂等操作。即使每次您运行lock
都有一些副作用,例如眨眼,汽车仍处于相同的锁定状态。
答案 12 :(得分:0)
我的5c: 在整合和网络化中,幂等性非常重要。 现实生活中的几个例子: 想象一下,我们将数据传送到目标系统。由一系列消息传递的数据。 1.如果序列在通道中混合会发生什么? (因为网络包总是:))。如果目标系统是幂等的,结果将不会有所不同。如果目标系统依赖于序列中的正确顺序,我们必须在目标站点上实现重新排序器,这将恢复正确的顺序。 2.如果有重复的消息,会发生什么?如果目标系统的通道未及时确认,则源系统(或通道本身)通常会发送该消息的另一个副本。因此,我们可以在目标系统端有重复的消息。 如果目标系统是幂等的,它会处理它并且结果不会有所不同。 如果目标系统不是幂等的,我们必须在通道的目标系统端实现重复数据删除器。
答案 13 :(得分:0)
简而言之,幂等操作意味着无论操作幂等操作多少次,操作都不会产生不同的结果。
例如,根据HTTP规范的定义,GET, HEAD, PUT, and DELETE
是幂等操作;但是POST and PATCH
不是。这就是为什么有时POST被PATCH取代的原因。
答案 14 :(得分:-2)
<强>重试安全的。强>
通常是了解计算机科学意义的最简单方法。