幂等性学习及接口的幂等性
幂等性学习
一:什么是幂等性
在这里需要有以下几个问题需要注意:
1:幂等性的实质是一次或多次请求同一个资源,其结果是相同的。其关注的是对资源产生的影响(副作用)而不是结果,结果可以不同。比如列表查询的时候,一边在save或者是update,而你这边还是在select,其结果肯定是不同的,但是你的select操作并未对数据(资源)产生影响(副作用);
2:幂等性不仅仅只是一次或者多次请求的时候对资源没有副作用。比如根据id对数据库的查询操作,此操作对数据库没有增删改,所以多次查询操作对数据库结果是没有任何影响的;
3:幂等性还包括了第一次请求资源的时候,对资源产生了副作用,但是在以后多次同样的请求操作的时候,都不会在对资源产生副作用了。比如我们根据id更新订单状态从支付中变为支付完成这个操作,在执行第一次的时候,会更新为支付完成。之后在根据这个id执行此操作,无论执行多少次其结果和第一次执行后的结果一样;
4:幂等性关注的是以后的多次请求是否对资源产生了副作用,而不是关注的结果;
5:需要说明的是网络超时、服务宕机等问题,不是幂等的范围。
幂等性是系统服务对外的一种承诺(注意,是一种承诺,而不是一种实现),接口服务提供方承诺只要调用接口成功了,外部多次调用对系统的影响是一致的。这里需要强调一点就是,声明为幂等的服务会认为调用方调用失败是常态,是正常业务,并且允许在调用失败后必然会有重试的。
二:什么情况下需要使用幂等
在我们开发中,经常会遇到一个头疼的事情—重复提交的情况。重复提交情况有多种原因产生的。如由于网络问题无法收到请求结果情况下而重新发起的请求或者是因为调用方前端操作抖动而造成的重复提交。
重复提交操作带来的严重后果在交易系统、支付系统中因重复提交而产生的问题尤其的明显。如:我们发起支付的时候向支付宝支付请求,无论是交易系统自身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:如果已经支付过,则返回支付成功;如果没有支付,在进行支付流程操作后,将订单状态修改为已支付。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
第一天 负载均衡之高并发发送
高并发发送: 1处:负载均衡 2处:数据库 在APP服务器多台情况下,如果用户登录,session怎么处理? 本文来源:凯哥Java(kaigejava) 个人博客:www.kaigejava.com 如下图: 说明: 如果用户登录的时候负载到01服务器上,当用户在操作其他的时候,如果被负载到02机器上。这个时候02机器上面就没有当前用户的session。用户就会被转跳到登陆页面。 解决方案: 1:可以把用户的session放置到cookie中 优点:解决了session没有的问题 缺点:session放在了用户的浏览器中,是不安全的 2:可以把用户的session放置到数据库中 优点:解决了session没有的问题 缺点:当用户量很大的时候,如果把session放置到数据库中,会造成数据库压力过大。从而使数据库运行不正常 3:可以把用户的session放在缓存服务器中 最好的解决的方案是:放在缓存服务器中。这里推荐两种缓存服务器:memcached、redis 要求:memcached/redis必须是集群 4:tomcat共享session 缺点:当tomcat数量过多的时候及其影...
- 下一篇
看了这个Java实习生入职测试题后,幸亏我不是实习生
看了这个Java实习生入职测试题后,幸亏我不是实习生 一个Java实习生的入职测试题,你能答对几个? 今天在某APP中看到,有实习生放出的Java实习生入职测试题。看完之后,很庆幸自己不是实习生。 本文来源:公众号:凯哥Java(kaigejava) 个人博客:www.kaigejava.com 我们来一起看看题目吧: 1:String类为什么是fianl的? 2:JDK8中的HashMap的源码,实现原理,底层结构? 3:反射中,Class.forName和classloader的区别? 4:session和cookie的区别和联系,session的生命周期,多个服务部署时候session管理? (ps:凯哥备注:这个不是考分布式session管理吗?) 5:Java中的队列都有哪些?有什么区别? 6:详谈一下Java的内存模型以及GC算法? (JVM的算法) 7:Java10、Java11的新特性?(额,这个凯哥也不知道) 8:Java内存泄漏的问题调查定位;jmap,jstack的使用 9:Spring的体现结构和jar用途 10:Spring MVC的运行原理 11:Sprin...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Mario游戏-低调大师作品