|
|
|
|
移动端
创建专栏

并发扣款一致性,幂等性问题,这个话题还没聊完!!!

本文来源:http://www.2233122.com/www_zol_com_cn/

太阳城娱乐网最快登入,【全能输入】全面支持拼音、手写、语音、笔画、五笔【畅快表达】海量词库,分秒匹配【妙算引擎】动态预测,智能纠错【贴心手写】首字注音,生僻字输入无忧【智能语音】高效识别,说话实时变文字【文字扫描】纸面文字拍照输入【快捷短语】常用语、流行语一键输入【个性皮肤】新鲜主题,悦耳按键音,惊喜动画【实力表情】魔性斗图,有料图表情,鲜萌颜文字,生动Emoji手机输入,依然搜狗!搜狗手机输入法8.6更新内容1.快速分享优化:完善搜索结果,改进分享体验。下一步工作,吉林省委省政府已经作出了一些部署,提出的目标是坚决打赢全面振兴这场硬仗。尤其是在过去的三个月,N系列手机销量突破了200万台,其中N4S获得了好评率高达98%的好成绩。◇收集随从,排兵布阵◇熟悉的卡牌系统,不一样的玩法。

记者\编辑职位描述负责报纸内容的策划、组稿、采写工作。  【天极网手机频道】存在感对于品牌来说是一个非常重要的指标。分析师分了七个部分:虚拟化、基础即服务,企业平台级服务,云的存储服务,商务智能,社交,销售自动化。本期女主播:Wing职业:PConline秘密小组编辑简介:楼上放屁!      本期节目我们请来了以为特别的嘉宾:雷神911M笔记本电脑。

独立显卡核心温度状态如图,未开强冷时最高温度63℃,开启强冷后温度降到54℃。本期女主播:Wing职业:PConline秘密小组编辑简介:楼上放屁!      本期节目我们请来了以为特别的嘉宾:雷神911M笔记本电脑。“当然,我们相信未来还会有更多的盈利模式逐步被发现,或者说这些盈利模式会有一定组合、侧重。  【通信产业网讯】(野村综研通信ICT事业咨询部咨询顾问孙晓道)从2013年12月工信部正式向三大运营商发放TD-LTE制式的4G牌照算起,到如今4G也行将走过三年的历程。

《并发扣款,如何保证数据的一致性?》,分享了同一个用户并发扣款时,有一定概率出现数据不一致,可以使用CAS乐观锁的方式,在不降低吞吐量,并且只有少量修改的情况下,保证数据的一致性。

作者:58沈剑|2019-09-08 22:45

并发扣款,如何保证数据的一致性?》,分享了同一个用户并发扣款时,有一定概率出现数据不一致,可以使用CAS乐观锁的方式,在不降低吞吐量,并且只有少量修改的情况下,保证数据的一致性。

文章发布不到24小时,就有近200的评论。

其中,问的比较多的是ABA问题,这个问题已经在《并发扣款一致性优化,CAS下ABA问题,这个话题还没聊完!!!》中扩展。 其次,问的比较多的是作业题,为什么一定要用select&set的方式进行余额写回:

  1. UPDATE t_yue SET money=$new_money WHERE uid=$uid AND money=$old_money;  

为什么不能采用直接扣减的方法:

  1. UPDATE t_yue SET moneymoney=money-$diff WHERE uid=$uid; 

很人说,在并发情况下,会将money扣成负数。 为了保证余额不被扣成负数,再加一个where条件:

  1. UPDATE t_yue SET moneymoney=money-$diff WHERE uid=$uid AND money-$diff>0; 

这样是否可行?画外音:额,撇开业务不谈,这个SQL用列做运算,其实是不好的,建议使用:

  1. UPDATE t_yue SET moneymoney=money-$diff WHERE uid=$uid AND money>$diff; 

很遗憾,仍然不行。原因在《并发扣款,如何保证数据的一致性?》一文里点赞最多的评论,不幂等。画外音:说明绝大部分同学,能够回答正确作业。 聊幂等性之前,先看另一个测试用例的case。 假设有一个服务接口,注册新用户:

  1. bool RegisterUser($uid, $name){ 
  2.          /查看uid是否已经存在 
  3.          select uid from t_user where uid=$uid; 
  4.          /不是新用户,返回失败 
  5.          if(rows>0)return false; 
  6.          else{ 
  7.                    /把新用户插入用户表 
  8.                    insert into t_user values($uid, $name); 
  9.                    /返回成功 
  10.                    return true; 
  11.          } 

有一个测试工程师,对该接口写了一个测试用例:

  1. bool TestCase_RegisterUser(){ 
  2.          /造一些假数据 
  3.          long uid=123
  4.          String name='shenjian'
  5.          /调用被测试的接口 
  6.          bool resultRegisterUser(uid,name); 
  7.          /预期注册成功,对结果进行断言判断 
  8.          Assert(result,true); 
  9.          /返回测试结果 
  10.          return result; 

这是不是一个好的测试用例?这个用例存在什么问题?

你会发现,相同条件下,这个测试用例执行两次,得到的结果不一样:

  • 第一次执行,第一次造数据,调用接口,注册成功;
  • 第二次执行,又造了一次相同的数据,调用接口,注册会失败;这不是一个好的测试用例,多次执行结果不同。

什么是幂等性?

相同条件下,执行同一请求,得到的结果相同,才符合幂等性。

画外音:Google一下,比我解释得更好,但意思应该说清楚了。

如何将上面的测试用例改为符合“幂等性”的测试用例呢?

只需要加一行代码:

  1. bool TestCase_RegisterUser(){ 
  2.          /造一些假数据 
  3.          long uid=123
  4.          String name=’shenjian’; 
  5.          /先删除这个伪造的用户 
  6.          DeleteUser(uid); 
  7.          /调用被测试的接口 
  8.          bool resultRegisterUser(uid,name); 
  9.          /预期注册成功,对结果进行断言判断 
  10.          Assert(result,true); 
  11.          /返回测试结果 
  12.          return result; 

这样,在相同条件下,不管这个用例执行多少次,得到的测试结果都是相同的。 是不是对幂等性有点感觉了。 读请求,一般是幂等的。

写请求,视情况而定:

  • insert x,一般来说不是幂等的,重复插入得到的结果不一定一样
  • delete x,一般来说是幂等的,删除多次得到的结果仍相同
  • set a=x是幂等的
  • set a=a-x不是幂等的

因此,这么扣减余额:

  1. UPDATE t_yue SET money=$new_money WHERE uid=$uid AND money=$old_money; 

是幂等操作。

要是这么扣减余额:

  1. UPDATE t_yue SET moneymoney=money-$diff WHERE uid=$uid AND money-$diff>0; 

不是幂等操作。

聊到这里,或许有朋友要抬杠了,测试用例会重复执行,扣款怎么会重复执行呢?

重试。 重试,是异常处理里很常见的手段。

你在写业务的时候有没有写过这样的代码:

  1. result = DoSomething(); 
  2. if(false==result || TIMEOUT){ 
  3.          /错误,或者超时,重试一次 
  4.          resultDoSomething(); 
  5. return result; 

当然,又会有朋友抬杠了,我从来不重试!!!

画外音:额,这是合格,还是不合格呢?

你可以决定业务代码怎么写,你不能决定底层框架代码怎么写:

  • 站点框架有没有自动重试?
  • 服务框架有没有自动重试?
  • 服务连接池,数据库连接池有没有自动重试?

画外音:

  • 服务化分层的架构中,建议只入口层重试,服务层不要重试,防止雪崩;
  • dubbo底层,调用超时是默认重试的,这个设计不好;

因此,在有重试的架构体系里,幂等性是需要考虑的一个问题。

现在该懂了,为啥扣款和充值业务,一般使用:select&set,配合CAS方案

而不使用:set money-=X方案

画外音:充了100电话费,怎么多了200块?

知其然,知其所以然,希望大家有收获。

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】

太阳城娱乐网最快登入戳这里,看该作者更多好文

【编辑推荐】

  1. 一致性哈希算法很难?看完这篇全懂了
  2. 一致性Hash(Consistent Hashing)原理剖析
  3. 并发扣款,如何保证数据的一致性?
  4. 微服务分布式一致性模式
  5. 并发扣款一致性优化,CAS下ABA问题,这个话题还没聊完!!!
【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0
大家都在看
猜你喜欢
太阳城娱乐网最快登入
太阳城官方直营网登入 申博手机投注登入 申博娱乐手机登入网址 申博会员登入 www.86msc.com 申博太阳平台官方网站
菲律宾申博88msc娱乐 申博真人游戏登入 菲律宾申博真人娱乐登入 申博线路检测中心 www.666msa.com 申博电子游戏官网直营
www.sb99.com 申博138真人在线娱乐直营网 申博138游戏直营网 菲律宾申博网址登入 申博游戏手机网址 菲律宾太阳娱乐网址登入