幂等(idempotence)是来自于高等代数中的概念。 定义如下(加入了自己理解): 单目运算, x为某集合内的任意数, f为运算子如果满足f(x)=f(f(x)), 那么我们称f运算为具有幂等性(idempotent) 比如在实数集中,绝对值运算就是一个例子: abs(a)=abs(abs(a)) 双目运算,x为某集合内的任意数, f为运算子如果满足f(x,x)=x, f运算的前提是两个参数都同为x, 那么我们也称f运算为具有幂等性 比如在实数集中,求两个数的最大值的函数: max(x,x) = x, 还有布尔代数中,逻辑运算 "与", "或" 也都是幂等运算, 因为他们符合AND(0,0) = 0, AND(1,1) = 1, OR(0,0) = 0, OR(1,1) = 1 在将幂等性应用到软件开发中,需要一些更深的理解. 我的理解如下: 数学处理的是运算和数值, 程序开发中往往处理的是对象和函数. 但是我们不能简单地理解为数学幂等中的运算就是函数,而数值就是对象!! 比如有Person对象有两个属性weight和age,但是所有的function只能对其中一个属性操作. 所以从这个层面我们可以理解为: 函数只对该函数所操作的对象某个属性具有幂等性, 而不是说对整个对象有运算幂等性.
Person {
private int weight;
private int age;
//是幂等函数
public void setAge(int v){
this.age = v;
}
//不是幂等函数
public void increaseAge(){
this.age++;
}
//是幂等函数
public void setWeight(int v){
this.weight=v+10;//故意加10斤!!
}
}
还有一点必须要澄清的是: 幂等性所表达的概念关注的是数学层面的运算和数值, 并没有提及到数值的安全性问题. 比如上面的Person的setAge函数, 有两种case不是幂等性所关心的, 但程序开发却又必须要关心的: 1. 两个线程同时调用 2. 因为age从业务上讲不可能递减, 如果前一次调用设置是30岁, 后一次调用变成了10岁或是更离谱的 -1 岁 所以RESTful设计中将幂等性和安全性是作为两个不同的指标来衡量POST,PUT,GET,DELETE操作的:
幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试.
就象cache有cache基本实现范式一样, 幂等也有自己的固定外部调用范式
cache实现范式:
value getValue(key){
value = getValueFromCache(key);
if( value == null ){
value = readFromPersistence(key);
saveValueIntoCache(key,value);
}
return value;
}
幂等外部调用范式
client.age = 30;
while(一些退出条件){
try{
if(socket.setPersonAge(person,client.age) == FAILED){
int newAge = socket.getPersonAge();
//处理冲突问题: 因为age只可能越来越大,所以将client的age更新为server端更大的age
if(newAge>30){
client.age = newAge;
break;
} else{
//无法进行冲突解决,再次尝试
}
} else return;
} catch(Exception){
//发生网络异常, 再次尝试
}
}
幂等接口的内部实现需要有对内保护机制, 一般情况是用类似于乐观锁的版本机制.版本重点是体现时间的先后 |

Ecmall仿天猫2014多店铺商城
人气:2515
ecshop秒杀插件
人气:4582
ecshop仿莫菲尚品蛋糕食品
人气:2244
zencart英文服装鞋帽女士用
人气:2223
ecshop仿京东360top奢侈品模
人气:964
shopex绿色类凡客模板
人气:546