什么是幂等运算?
当前回答
如果一个操作执行多次等同于执行一次,那么它就是幂等的。
例如:将音量设置为20。 不管把电视的音量设置多少次为20,最终的结果都是20。即使一个进程执行该操作50/100次或更多,在进程结束时,卷也将为20。
反例:将音量增加1。如果一个进程执行该操作50次,则最终卷将为初始卷+ 50;如果一个进程执行该操作100次,则最终卷将为初始卷+ 100。正如您可以清楚地看到的,最终结果根据执行操作的次数而变化。因此,我们可以得出结论,这个运算不是幂等的。
我用粗体突出显示了最终结果。
如果你从编程的角度考虑,假设我有一个操作,其中一个函数f以foo作为输入,f的输出被设为foo。如果在进程结束时(执行此操作50/100次或更多次),我的foo变量保存的值是该操作只执行一次时的值,则该操作是幂等的,否则为NOT。
Foo = <某个随机值,比如-2>
{foo = f(foo)}花括号概括了该操作
如果f返回输入的平方,则运算不是幂等的。因为foo在最后会被(-2)提升到(执行操作次数)的次方
如果f返回输入的绝对值,则操作是幂等的,因为无论执行多少次操作,foo都将是abs(-2)。 这里,最终结果被定义为变量foo的最终值。
在数学意义上,幂等的含义略有不同: F (F (.... F (x))) = F (x) 这里f(x)的输出再次作为输入传递给f,这在编程中并不需要总是这样。
其他回答
对于工作流管理器(如Apache workflow),如果管道中的幂等操作失败,系统可以自动重试该任务而不影响系统。即使日志发生了变化,这也很好,因为您可以看到事件。
在这种情况下,最重要的是您的系统可以重试失败的任务,并且不会弄乱管道(例如,每次重试都在表中添加相同的数据)
幂等操作是一种可以应用多次而不改变结果(即系统状态)的操作、动作或请求,超出初始应用。
示例(web应用上下文):
IDEMPOTENT: Making multiple identical requests has the same effect as making a single request. A message in an email messaging system is opened and marked as "opened" in the database. One can open the message many times but this repeated action will only ever result in that message being in the "opened" state. This is an idempotent operation. The first time one PUTs an update to a resource using information that does not match the resource (the state of the system), the state of the system will change as the resource is updated. If one PUTs the same update to a resource repeatedly then the information in the update will match the information already in the system upon every PUT, and no change to the state of the system will occur. Repeated PUTs with the same information are idempotent: the first PUT may change the state of the system, subsequent PUTs should not.
非幂等性: 如果一个操作总是导致状态的变化,比如反复向用户发送相同的消息,导致每次都发送新消息并存储在数据库中,我们称该操作为NON-IDEMPOTENT。
NULLIPOTENT: 如果一个操作没有副作用,就像仅仅在网页上显示信息而没有对数据库进行任何更改(换句话说,你只是在读取数据库),我们说这个操作是NULLIPOTENT。所有get都应该是无效的。
当谈论系统的状态时,我们显然忽略了无害的和不可避免的影响,如日志和诊断。
任何操作,每n个结果都会产生与第1个结果值匹配的输出。例如,-1的绝对值是1。-1的绝对值的绝对值是1。-1绝对值的绝对值的绝对值等于1。等等。请参见:什么时候使用递归是非常愚蠢的?
只是想提出一个真实的用例来证明幂等性。在JavaScript中,假设你定义了一堆模型类(就像MVC模型一样)。它的实现方式通常是这样的(基本示例):
function model(name) {
function Model() {
this.name = name;
}
return Model;
}
然后你可以像这样定义新的类:
var User = model('user');
var Article = model('article');
但如果你试图通过模型(' User ')从代码的其他地方获取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;
}
通过添加缓存,每次你建模('user')它都是同一个对象,所以它是幂等的。所以:
model('user') === model('user');
无论调用该操作多少次,结果都是相同的。