成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

并發(fā)扣款一致性,冪等性問題,這個(gè)話題還沒聊完?。?!

開發(fā) 開發(fā)工具
《并發(fā)扣款,如何保證數(shù)據(jù)的一致性?》,分享了同一個(gè)用戶并發(fā)扣款時(shí),有一定概率出現(xiàn)數(shù)據(jù)不一致,可以使用CAS樂觀鎖的方式,在不降低吞吐量,并且只有少量修改的情況下,保證數(shù)據(jù)的一致性。

并發(fā)扣款,如何保證數(shù)據(jù)的一致性?》,分享了同一個(gè)用戶并發(fā)扣款時(shí),有一定概率出現(xiàn)數(shù)據(jù)不一致,可以使用CAS樂觀鎖的方式,在不降低吞吐量,并且只有少量修改的情況下,保證數(shù)據(jù)的一致性。

[[276190]]

文章發(fā)布不到24小時(shí),就有近200的評(píng)論。

其中,問的比較多的是ABA問題,這個(gè)問題已經(jīng)在《并發(fā)扣款一致性優(yōu)化,CAS下ABA問題,這個(gè)話題還沒聊完!!!》中擴(kuò)展。 其次,問的比較多的是作業(yè)題,為什么一定要用select&set的方式進(jìn)行余額寫回:

  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; 

很人說,在并發(fā)情況下,會(huì)將money扣成負(fù)數(shù)。 為了保證余額不被扣成負(fù)數(shù),再加一個(gè)where條件:

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

這樣是否可行?畫外音:額,撇開業(yè)務(wù)不談,這個(gè)SQL用列做運(yùn)算,其實(shí)是不好的,建議使用:

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

很遺憾,仍然不行。原因在《并發(fā)扣款,如何保證數(shù)據(jù)的一致性?》一文里點(diǎn)贊最多的評(píng)論,不冪等。畫外音:說明絕大部分同學(xué),能夠回答正確作業(yè)。 聊冪等性之前,先看另一個(gè)測(cè)試用例的case。 假設(shè)有一個(gè)服務(wù)接口,注冊(cè)新用戶:

  1. bool RegisterUser($uid, $name){ 
  2.          //查看uid是否已經(jīng)存在 
  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.          } 

有一個(gè)測(cè)試工程師,對(duì)該接口寫了一個(gè)測(cè)試用例:

  1. bool TestCase_RegisterUser(){ 
  2.          //造一些假數(shù)據(jù) 
  3.          long uid=123
  4.          String name='shenjian'
  5.          //調(diào)用被測(cè)試的接口 
  6.          bool resultRegisterUser(uid,name); 
  7.          //預(yù)期注冊(cè)成功,對(duì)結(jié)果進(jìn)行斷言判斷 
  8.          Assert(result,true); 
  9.          //返回測(cè)試結(jié)果 
  10.          return result; 

這是不是一個(gè)好的測(cè)試用例?這個(gè)用例存在什么問題?

你會(huì)發(fā)現(xiàn),相同條件下,這個(gè)測(cè)試用例執(zhí)行兩次,得到的結(jié)果不一樣:

  • 第一次執(zhí)行,第一次造數(shù)據(jù),調(diào)用接口,注冊(cè)成功;
  • 第二次執(zhí)行,又造了一次相同的數(shù)據(jù),調(diào)用接口,注冊(cè)會(huì)失敗;這不是一個(gè)好的測(cè)試用例,多次執(zhí)行結(jié)果不同。

什么是冪等性?

相同條件下,執(zhí)行同一請(qǐng)求,得到的結(jié)果相同,才符合冪等性。

畫外音:Google一下,比我解釋得更好,但意思應(yīng)該說清楚了。

如何將上面的測(cè)試用例改為符合“冪等性”的測(cè)試用例呢?

只需要加一行代碼:

  1. bool TestCase_RegisterUser(){ 
  2.          //造一些假數(shù)據(jù) 
  3.          long uid=123
  4.          String name=’shenjian’; 
  5.          //先刪除這個(gè)偽造的用戶 
  6.          DeleteUser(uid); 
  7.          //調(diào)用被測(cè)試的接口 
  8.          bool resultRegisterUser(uid,name); 
  9.          //預(yù)期注冊(cè)成功,對(duì)結(jié)果進(jìn)行斷言判斷 
  10.          Assert(result,true); 
  11.          //返回測(cè)試結(jié)果 
  12.          return result; 

這樣,在相同條件下,不管這個(gè)用例執(zhí)行多少次,得到的測(cè)試結(jié)果都是相同的。 是不是對(duì)冪等性有點(diǎn)感覺了。 讀請(qǐng)求,一般是冪等的。

寫請(qǐng)求,視情況而定:

  • insert x,一般來說不是冪等的,重復(fù)插入得到的結(jié)果不一定一樣
  • delete x,一般來說是冪等的,刪除多次得到的結(jié)果仍相同
  • 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; 

不是冪等操作。

聊到這里,或許有朋友要抬杠了,測(cè)試用例會(huì)重復(fù)執(zhí)行,扣款怎么會(huì)重復(fù)執(zhí)行呢?

重試。 重試,是異常處理里很常見的手段。

你在寫業(yè)務(wù)的時(shí)候有沒有寫過這樣的代碼:

  1. result = DoSomething(); 
  2. if(false==result || TIMEOUT){ 
  3.          //錯(cuò)誤,或者超時(shí),重試一次 
  4.          resultDoSomething(); 
  5. return result; 

當(dāng)然,又會(huì)有朋友抬杠了,我從來不重試!!!

畫外音:額,這是合格,還是不合格呢?

你可以決定業(yè)務(wù)代碼怎么寫,你不能決定底層框架代碼怎么寫:

  • 站點(diǎn)框架有沒有自動(dòng)重試?
  • 服務(wù)框架有沒有自動(dòng)重試?
  • 服務(wù)連接池,數(shù)據(jù)庫連接池有沒有自動(dòng)重試?

畫外音:

  • 服務(wù)化分層的架構(gòu)中,建議只入口層重試,服務(wù)層不要重試,防止雪崩;
  • dubbo底層,調(diào)用超時(shí)是默認(rèn)重試的,這個(gè)設(shè)計(jì)不好;

因此,在有重試的架構(gòu)體系里,冪等性是需要考慮的一個(gè)問題。

現(xiàn)在該懂了,為啥扣款和充值業(yè)務(wù),一般使用:select&set,配合CAS方案

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

畫外音:充了100電話費(fèi),怎么多了200塊?

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

【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文

 

責(zé)任編輯:趙寧寧 來源: 51CTO
相關(guān)推薦

2019-09-05 08:54:38

一致性CASABA

2022-10-19 12:22:53

并發(fā)扣款一致性

2019-08-30 12:46:10

并發(fā)扣款查詢SQL

2024-01-10 08:01:55

高并發(fā)場(chǎng)景悲觀鎖

2022-08-11 07:55:05

數(shù)據(jù)庫Mysql

2024-04-11 13:45:14

Redis數(shù)據(jù)庫緩存

2024-11-14 07:10:00

2016-11-29 09:00:19

分布式數(shù)據(jù)一致性CAS

2017-07-25 14:38:56

數(shù)據(jù)庫一致性非鎖定讀一致性鎖定讀

2022-12-14 08:23:30

2022-09-06 15:30:20

緩存一致性

2019-02-13 11:04:42

系統(tǒng)緩存軟件

2023-12-01 13:51:21

數(shù)據(jù)一致性數(shù)據(jù)庫

2023-04-13 08:15:47

Redis緩存一致性

2021-04-24 16:58:03

數(shù)據(jù)庫工具技術(shù)

2019-09-18 08:41:53

并發(fā)扣減一致性redis

2021-02-05 08:00:48

哈希算法?機(jī)器

2021-02-02 12:40:50

哈希算法數(shù)據(jù)

2019-03-27 13:56:39

緩存雪崩穿透

2025-03-10 09:20:00

庫存異常Redis架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩精品免费视频 | 欧美色综合一区二区三区 | 本道综合精品 | 欧美极品少妇xxxxⅹ免费视频 | 色综合一区二区 | 国产乱码精品一区二区三区中文 | 午夜精品一区 | 亚洲午夜视频 | 天天看天天操 | 久久精品一区二区三区四区 | 国产精品美女久久久久aⅴ国产馆 | 亚洲精品永久免费 | 一级h片 | 久久久国产亚洲精品 | 久久久久av | 午夜精品久久久久久不卡欧美一级 | 久久久久久久夜 | 国产一二区在线 | 亚洲欧美精品在线观看 | 欧美日高清视频 | 男女在线免费观看 | 欧美一区二区三区视频 | 国产精品一区二 | 夜夜草| 亚洲逼院 | 亚洲天天干 | 国产露脸国语对白在线 | 色综合久久久 | 羞羞的视频网站 | 久久久久久国产 | 天天草天天爱 | 国产精品一区二区三区99 | 国产精品国产三级国产aⅴ浪潮 | 成人午夜看片 | 亚洲女人天堂成人av在线 | 久久久久网站 | 午夜影院官网 | 久久丁香| 欧美日韩一区不卡 | 国产综合区 | 久久精品亚洲欧美日韩精品中文字幕 |