国内最专业的IT技术学习网

UI设计

当前位置:主页 > UI设计 >

并发扣款,如何保证数据的一致性?

发布时间:2019/08/31标签:   余额    点击量:

原标题:并发扣款,如何保证数据的一致性?
持续解答星球水友发问。 沈教师,咱们有个营业,统一个用户在并发“查问,逻辑盘算,扣款”的情形下,余额能够呈现纷歧致,叨教有甚么优化方式么? 扣款的营业场景是怎么的?用户购置商品的进程中,要对余额停止查问与修正,大抵的营业流程以下:第一步,从数据库查问用户现不足额:SELECTmoneyFROMt_yueWHEREuid=$uid;无妨设查问进去的$old_money=100元。第二步,营业层实行营业逻辑盘算,比方: 先查问购置商品的价钱,比方是80元; 再查问产物能否有运动,以及运动扣头,比方是9折; 比对余额能否充足,充足时才往下走;if($old_money>80*0.9){$new_money=$old_money-80*0.9=28}else{return"Notenoughminerals";}第三步,将数据库中的余额停止修正。UPDATEt_yueSETmoney=$new_moneyWHEREuid=$uid;在并发量低的情形下,这个流程没有任何成绩,原有金额100元,购置了80元的九折商品(72元),残余28元。统一个用户,并发扣款能够呈现甚么成绩?在散布式情况中,假如并发量很大,这类“查问+修正”的营业有必定几率呈现数据纷歧致。极限情形下,能够呈现如许的异样流程:步调一,营业1和营业2并发查问余额,是100元。画外音:这些并发查问,是在差别的站点实例/效劳实例上实现的,过程内互斥锁确定处理不了。步调二,营业1和营业2并发停止逻辑盘算,算出各自营业的余额,假定营业1算出的余额是28元,营业2算出的余额是38元。步调三,营业1对数据库中的余额进步行修正,设置成28元。营业2对数据库中的余额落后行修正,设置成38元。此时异样呈现了,原有金额100元,营业1扣除了72元,营业2扣除了62元,最初残余38元。画外音:假定营业1先写回余额,营业2再写回余额。罕见的处理计划?关于此案例,统一个用户,并发扣款时,有小几率会呈现异样,能够对每一个用户停止散布式锁互斥,比方:在redis/zk里抢到一个key才干持续操纵,不然制止操纵。这类达观锁计划确切可行,但要引入额定的组件(redis/zk),而且会下降吞吐量。关于小几率的纷歧致,有没有悲观锁的计划呢?对并发扣款停止进一步的剖析发觉:(1) 营业1写回时,旧余额100,这是一个初始状况;新余额28,这是一个停止状况。实践上只要在旧余额为100时,新余额才应当写回胜利。而营业1并发写回时,旧余额确切是100,理当写回胜利。(2) 营业2写回时,旧余额100,这是一个初始状况;新余额28,这是一个停止状况。实践上只要在旧余额为100时,新余额才应当写回胜利。可现实上,这个时间数据库中的金额曾经变成28了,以是营业2的并发写回,不该该胜利。怎样低本钱实行悲观锁?在set写回的时间,加上初始状况的前提compare,只要初始状况稳定时,才同意set写回胜利,Compare And Set(CAS),是一种罕见的下降读写锁抵触,保障数据分歧性的方式。此时营业要怎样改?应用CAS处理高并发时数据分歧性成绩,只要要在停止set操纵时,compare初始值,假如初始值变更,不同意set胜利。详细到这个case,只要要将:UPDATEt_yueSETmoney=$new_moneyWHEREuid=$uid;进级为:UPDATEt_yueSETmoney=$new_moneyWHEREuid=$uidANDmoney=$old_money;

版权信息Copyright © IT技术教程 版权所有    ICP备案编号:鲁ICP备09013610号