幂等性(Idempotence)。在HTTP/1.1规范中幂等性的定义是:前端
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.数据库
幂等性:就是用户对于同一操做发起的一次请求或者屡次请求的结果是一致的,不会由于屡次点击而产生了反作用。网络
那么咱们为何须要接口具备幂等性呢?设想一下如下情形:并发
在分布式环境中,网络环境更加复杂,因前端操做抖动、网络故障、消息重复、响应速度慢等缘由,对接口的重复调用几率会比集中式环境下更大,尤为是重复消息在分布式环境中很难避免。分布式
接口的幂等性实际上就是接口可重复调用,在调用方屡次调用的状况下,接口最终获得的结果是一致的。有些接口能够自然的实现幂等性,好比查询接口,对于查询来讲,你查询一次和两次,对于系统来讲,没有任何影响,查出的结果也是同样。ide
除了查询功能具备自然的幂等性以外,增长、更新、删除都要保证幂等性。那么如何来保证幂等性呢?高并发
幂等须要经过惟一的业务单号来保证。也就是说相同的业务单号,认为是同一笔业务。使用这个惟一的业务单号来确保,后面屡次的相同的业务单号的处理逻辑和执行效果是一致的。
下面以支付为例,在不考虑并发的状况下,实现幂等很简单:①先查询一下订单是否已经支付过,②若是已经支付过,则返回支付成功;若是没有支付,进行支付流程,修改订单状态为‘已支付’。设计
上述的保证幂等方案是分红两步的,第②步依赖第①步的查询结果,没法保证原子性的。在高并发下就会出现下面的状况:第二次请求在第一次请求第②步订单状态尚未修改成‘已支付状态’的状况下到来。既然得出了这个结论,余下的问题也就变得简单:把查询和变动状态操做加锁,将并行操做改成串行操做。日志
一、悲观锁,select for update,整个执行过程当中锁定该订单对应的记录。二、乐观锁,affectrows = db.update(“update payorder set state=’已支付’ where orderid=$orderid and state=’未支付’ “),若是affectrows=1,执行充值,不然返回已处理。三、定义防重复表,orderid为unique key或者primary key,执行前,先insert,若insert成功则执行充值,不然返回已处理