幂等性学习前端
一:什么是幂等性java
在这里须要有如下几个问题须要注意:sql
1:幂等性的实质是一次或屡次请求同一个资源,其结果是相同的。其关注的是对资源产生的影响(反作用)而不是结果,结果能够不一样。好比列表查询的时候,一边在save或者是update,而你这边仍是在select,其结果确定是不一样的,可是你的select操做并未对数据(资源)产生影响(反作用);数据库
2:幂等性不只仅只是一次或者屡次请求的时候对资源没有反作用。好比根据id对数据库的查询操做,此操做对数据库没有增删改,因此屡次查询操做对数据库结果是没有任何影响的;网络
3:幂等性还包括了第一次请求资源的时候,对资源产生了反作用,可是在之后屡次一样的请求操做的时候,都不会在对资源产生反作用了。好比咱们根据id更新订单状态从支付中变为支付完成这个操做,在执行第一次的时候,会更新为支付完成。以后在根据这个id执行此操做,不管执行多少次其结果和第一次执行后的结果同样;并发
4:幂等性关注的是之后的屡次请求是否对资源产生了反作用,而不是关注的结果;ide
5:须要说明的是网络超时、服务宕机等问题,不是幂等的范围。学习
幂等性是系统服务对外的一种承诺(注意,是一种承诺,而不是一种实现),接口服务提供方承诺只要调用接口成功了,外部屡次调用对系统的影响是一致的。这里须要强调一点就是,声明为幂等的服务会认为调用方调用失败是常态,是正常业务,而且容许在调用失败后必然会有重试的。spa
来源:凯哥Java(kaigejava)设计
二:什么状况下须要使用幂等
在咱们开发中,常常会遇到一个头疼的事情—重复提交的状况。重复提交状况有多种缘由产生的。如因为网络问题没法收到请求结果状况下而从新发起的请求或者是由于调用方前端操做抖动而形成的重复提交。
重复提交操做带来的严重后果在交易系统、支付系统中因重复提交而产生的问题尤为的明显。如:咱们发起支付的时候向支付宝支付请求,不管是交易系统自身bug仍是交易系统与支付宝之间的网络问题致使重复发送,支付宝应该而且必须只能扣用户一次钱的。在这种需求下的系统在设计的时候,咱们就须要将系统或者服务设计成幂等的。
三:幂等和防重复提交比较
重复提交:重复提交是在第一次请求成功的状况下,人为的进行屡次操做,从而致使不知足幂等性要求的服务屡次改变数据状态。
幂等:更多使用的状况是第一次请求知道结果(好比常见的网络抖动致使链接超时)或者失败异常状况下,发起屡次请求的,其目的是屡次确认第一次请求成功,却不会由于屡次请求而出现屡次的状态变化。
什么状况下须要保障幂等性?
在这里,咱们以sql为例来说解。在下面三种场景中,只要第三种场景须要开发人员使用其余策略来保障幂等性:
1:查询状况
Select * from table where id = 2
不管执行多少次都不会对资源形成反作用,因此能够说是自然的幂等
2:根据id更新
Update table set status =1 where id =2
不管执行成功多少次状态都是一致的,第一次执行成功对资源形成的反作用和屡次执行成功对数据形成的反作用是同样的。所以能够说这种场景也是幂等操做
3:不是幂等状况
Update table set version = version+1 where id = 2
每次执行的结果都会发生变化,也就是说对资源形成了反作用,这种不是幂等的。这种状况若是想要保证幂等,语句能够这么写:update table set version = version+1 where id = 2 and version = 1.这样就能够保证幂等了。
为何要设计幂等性的服务?
幂等性的服务可使得客户端的处理业务逻辑变的简单了,可是确实以牺牲服务端逻辑变复杂为代价的。由于在知足幂等服务的需求下逻辑至少须要包含如下两点:
1:首选去查询上一次的执行状态(结果),若是没有则认为是第一次请求。这样就增长了业务难度
2:在服务改变状态的业务逻辑前,保证防重复提交的逻辑
幂等的不足:
经过上面咱们知道了幂等服务是以牺牲服务提供者逻辑和成本为代价的。因此,是否有必要,须要根据具体场景具体来分析的。所以除了业务上的特殊要求外,尽可能不要提供幂等的接口。
1:增长了额外的控制幂等的业务逻辑,复杂了业务功能;
2:把并行执行的功能改成串行执行,这样就下降了执行的效率。
保证幂等策略
其实在保证幂等的业务会经过惟一的业务单号来保证的。也就是说相同的单号,被认为是同一笔业务。使用惟一的业务单号来确保,后面屡次相同的业务单号的的处理逻辑和执行兄啊过是一致的。咱们以常见的支付为例(在不考虑并发状况下),实现幂等很简单:
1:先查询一下订单是否已经支付过
2:若是已经支付过,则返回支付成功;若是没有支付,在进行支付流程操做后,将订单状态修改成已支付。