比如我想要创建一个名称叫3y的订单:,使用POST多次请求,此时可能就会创建多个名称为3y的订单,这个订单(资源)是会多次变化的,每次请求的资源状态都会变化!
题外话:
HTTP协议本身是一种面向资源的应用层协议,但对HTTP协议的使用实际上存在着两种不同的方式:一种是RESTful的,它把HTTP当成应用层协议,比较忠实地遵守了HTTP协议的各种规定(充分利用了HTTP的方法);另一种是SOA的,它并没有完全把HTTP当成应用层协议,而是把HTTP协议作为了传输层协议,然后在HTTP之上建立了自己的应用层协议
参考资料:
理解HTTP幂等性#!comments
如何理解RESTful的幂等性
浅谈HTTP中Get与Post的区别
HTTP 请求中 POST 和 GET 请求的区别?https://www.zhihu.com/question/27622127/answer/37676304
9.2接口幂等性在查阅资料的时候,可以发现很多博客都讲了接口的幂等性。从上面我们也可以看出,POST方法是非幂等的。但我们可以通过一些手段来令POST方法的接口变成是幂等的。
说了那么多,那接口设计成幂等的好处是什么????
举个例子说一下非幂等的坏处:
3y大一的时候是要抢体育课的,但学校的抢课系统做得贼烂(延迟很高)。我想要抢到课,就开了10多个Chrome标签页去抢(即使某个Chrome标签页崩了,我还有另外的Chrome标签页是可用的)。我想抢到乒乓球或者羽毛球。
抢课时间一到,我就轮着点击我要想抢的乒乓球或者羽毛球。如果系统设计得不好,这个请求是非幂等的(或者说事务控制得不好),我手速足够快&&网络足够好,那我很可能抢到了多次乒乓球或者羽毛球的课程了。(这是不合理的,一个人只能选一门课,而我抢到了多门或者多次重复的课)
涉及到商城的应用场景可能就是:用户下了多个重复的订单了
如果我的抢课接口是幂等的话,那就不会出现这个问题了。因为幂等是多次请求某一个资源应该具有同样的副作用。
在数据库后台最多只会有一条记录,不存在抢到多门课的现象了。
说白了,设计幂等性接口就是为了防止重复提交的(数据库出现多条重复的数据)!
网上有博主也分享了几条常见解决重复提交的方案:
同步锁(单线程,在集群可能会失效)
分布式锁如redis(实现复杂)
业务字段加唯一约束(简单)
令牌表+唯一约束(简单推荐)---->实现幂等接口的一种手段
mysql的insert ignore或者on duplicate key update(简单)
共享锁+普通索引(简单)
利用MQ或者Redis扩展(排队)
其他方案如多版本控制MVCC 乐观锁 悲观锁 状态机等。。
参考资料:
分布式系统接口幂等性
如何避免下重复订单https://www.jianshu.com/p/e618cc818432
关于接口幂等性的总结https://www.jianshu.com/p/6eba27f8fb03
使用数据库唯一键实现事务幂等性
API接口非幂等性问题及使用redis实现简单的分布式锁https://blog.csdn.net/rariki/article/details/50783819
最后如果以上有理解错的地方,或者说有更好的理解方式,希望大家不吝在评论区下留言。共同进步!
如果想看更多的原创技术文章,欢迎大家关注我的微信公众号:Java3y。Java技术群讨论:742919422。公众号还有海量的视频资源哦,关注即可免费领取。
可能感兴趣的链接:
文章的目录导航(微信公众号端):https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang
文章的目录导航(PC端):
海量精美脑图: