接口幂等性和并发安全

接口幂等性和并发安全区别

概要

幂等和并发安全困扰本人好些天了,百思不得其解,遂有边写边思考边分析之想法,内容仅供参考,若有不当,还望不吝指出,万分感谢。关于幂等和并发的定义想必大家在大量的博客里找到很多答案了。
首先幂等直白点说就是同一接口一次执行和多次执行结果都一样,结果都一样的意思是,调用一次的结果是什么,调用多次的结果就是什么;而并发安全表示,同一个接口在并发调用后,结果必须要达到预期的结果,预期的结果意思是并发调用的多个结果的叠加结果。怎么理解这句话呢。

示例

场景一:当前存在多个待支付的订单,选择一个订单进行支付,支付中由于网络等原因支付结果返回时间较长,此时有多次点击支付按钮,或者在多个设备上登录了同一个账号并同时对同一订单进行支付,此场景的预期结果是我们只能支付一次而不会支付多次。

场景二:提交了多个订单后,同时支付,调用支付接口,那么最终扣除的金额必须是多个订单支付额的总和。

分析:以上两个场景相同点是都只调用了一个接口。不同点是,场景一中,相同设备上多次点击支付,支付的订单是同一个,操作的对象是相同的,条件相同,可以认为是同一操作,此操作执行一次的结果就是该订单支付成功一次,扣款一次,执行多次的结果同样是订单只支付成功一次,只扣款一次,所以此接口是需要支持幂等的接口;场景二中调用支付接口,操作对象不同,我们认为他不是同一操作,此时调用一次的结果是一个订单支付成功,扣款一次,多次调用的结果是多个订单都支付成功,每个订单扣款一次,预期的结果是扣款金额是多个订单支付金额的总和,是多次调用结果的叠加,场景一种的多个设备同时支付我们也认为不是同一操作,同样多设备支付只会扣款一次,两种情况我们都存在并发调用,但是要保证数据准确性所以接口也要支持并发安全。

总结:所以由此示例可以总结幂等和并发安全相同点是,同时调用同一接口;不同点是如果接口支持幂等,校验的是多次调用是不是同一操作,对同一操作,多次调用结果不会发生变化;直观表现为,只有一次调用执行了业务逻辑;如果接口需要并发安全,多次调用需要完整并正确的执行,对于并发调用的结果必须是多次同时调用仍然能达到预期的结果,直观表现为每个调用都执行了业务逻辑,但是结果必须达到预期结果。所以幂等和并发安全是不同的概念,一个接口可以同时支持幂等和并发,也可以都不支持,也可以只支持一个。

方案

幂等性:网上搜寻到的幂等性解决方案基本囊括:数据库唯一索引、防重表、token机制、悲观锁、乐观锁、redis分布式锁,详细解述可百度查阅。
并发安全:并发安全就我目前使用最多的就是锁了,对于java中的锁那就各种各样,千奇百怪了,同样对于现在的分布式系统来说,最常用的还是分布式锁了。
那具体分析下看看;

数据库唯一索引:首先数据库唯一索引的方案是数据库建立唯一索引,提交调用接口时没有违反唯一索引则执行成功,违反则失败。此方案对于接口幂等性和并发安全性来说,插入时是可行的,如果是修改操作,比方说每次修改一个值减一,那唯一索引就没有啥意义了,无法保证接口幂等性也不能保证高并发下数据的准确性,另外对于唯一索引的选择也不是那么好选择的,并不是每个操作都一定有唯一索引的。

悲观锁、乐观锁:也是从数据库层面,悲观锁锁住要操作的数据,乐观锁采用version字段,每次修改校验version值。分析一下,首先悲观锁容易造成锁表,这方面就不建议采纳;另外如果我是插入操作,就创建订单来说,我多次点击提交按钮或者多设备同时点击提交按钮,也无法保证我只生成一条订单数据;而仅仅是修改操作的话,大部分业务场景对于幂等性是可以的,并发安全性则需要在修改失败后进行重试,不太能保证高并发下的数据准确性。

token和防重表:意思差不多,总的来说是记录一个全局唯一的token来标识每次请求操作,详细可百度。token机制是存在一个交互的,操作提交前先从后端获取一个token,而后端记录这个token,提交时携带这个token,后端查到token表示是第一次请求,此时后端删除token,下次再重复提交将查不到token直接返回。高并发安全这个是不行的,没太大关系,那幂等性呢,思考一下,这个token是在进入可提交页面之前获取的,那么在当前页面没动的情况下,那确实你只能提交一次,点多少次只有第一次有效果,当要重新获取token的话需要退出去重新进来,比如创建订单,如果第一次进去之前创建成功了,后面就没法再进这个订单的创建页面了,如果第一次创建失败了,那重新进来还是可以再创建的,支付接口,第一次支付成功了,退出去也没法再进当前订单的支付页面了,第一次支付失败了,仍然可以支付,当然有时候一个操作设计到多个服务或者多个系统,存在超时的情况,所以适当在下游系统进行状态校验也是有必要的。所以按照这个分析,token机制来进行幂等性校验是可行的。至于防重表,意思差不多,但是要建表,不方便。

redis分布式锁(或其他分布式锁): 我们说锁是并发安全广泛的解决方案,那自然分布式锁是可以解决并发安全的。那幂等性呢,分析一下,我们说幂等性主要就是校验是否是同一操作,那我们在获取锁的时候只要能保证锁的key能标识是否是同一操作就可以实现幂等性呢。答案我认为是可以的,所以使用分布式锁实现幂等性的关键同样在于怎么标识同一操作。

总结

接口幂等表示的是对同一操作,接口调用一次和调用多次的结果都是相同的;接口并发安全表示,同时调用接口,仍能达到我们预期的结果,保证数据的准确性。是两个不同的概念,可以理解为,幂等性的多次调用是有先后的,而并发安全的多次调用是同时的,但是要保证并发的数据准确性。
幂等性我们可以采用token机制或者分布式锁机制,并发安全我们可以使用分布式锁机制。

仍然以支付为例,连续多次点击支付,token校验幂等方式的原理是只有第一次会真正执行支付,后面的请求被拦在幂等校验之外;分布式锁方式原理类似;并发安全则是在执行支付过程中保证支付逻辑执行的准确性。

写的有点乱,自我批评一下。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值