并發(fā)扣庫存問題總結(jié)

無論是日常工作中降铸,還是面試問題中,并發(fā)扣庫存都是一個很常見的場景摇零,正好業(yè)務(wù)里有這樣的場景推掸,可以對這類問題做一下總結(jié)。

一驻仅、場景描述

負(fù)責(zé)的項目里面有2個扣庫存的場景:
1.產(chǎn)品1:線上招募人員的產(chǎn)品谅畅,招募是有人數(shù)限制的,每招募成功1人噪服,扣減庫存1毡泻,直到庫存為0,自動停止招募粘优。
2.產(chǎn)品2:用戶秒殺產(chǎn)品仇味,用戶在同一個時間點呻顽,同時搶一件有庫存的商品。

一次扣庫存邪铲,可以分解為以下3個動作:
step1:查詢最新庫存(query
step2:檢查庫存是否足夠(內(nèi)存計算)
......
step3:更新庫存(update

二芬位、問題

1.單用戶重復(fù)提交未做冪等

用戶同時提交了2次扣庫存操作,因未做冪等带到,導(dǎo)致一次購買扣減2次庫存昧碉。

2.多用戶并發(fā)場景下庫存超賣

2個用戶搶1個庫存,查詢到的庫存都是1揽惹,檢查庫存足夠被饿,然后都去扣減庫存,庫存變成-1搪搏,發(fā)生了超賣狭握。

三、常見解法

對于第一個問題:
1.前端做防重機制防止用戶二次提交請求疯溺。

2.后端做冪等處理论颅,用戶請求帶業(yè)務(wù)token,進(jìn)行校驗囱嫩,重復(fù)token直接返回恃疯。

對于第二個問題:
1.直接扣庫存,不預(yù)檢查庫存update stock_table set stock = stock - 1 where stock-1 >= 0 and id = xxx墨闲,缺點是不通用今妄,比如業(yè)務(wù)上要求庫存除了有reduce還有add操作。

2.悲觀鎖鸳碧,將扣庫存操作(step1->3)變成只能串行盾鳞,缺點是同一時間只能有一個用戶來操作庫存,導(dǎo)致并發(fā)量不高(無論是通過synchronized關(guān)鍵字瞻离、數(shù)據(jù)庫鎖比如select for update腾仅、分布式鎖等各種方式加鎖,本質(zhì)都是一樣的)

3.樂觀鎖CAS方案:相比較方法1套利,庫存增加版本字段version推励,在更新庫存時比較版本號例如update stock_table set version = old_version + 1,stock = stock - 1 where version = query_version and id = xxx,只有版本號沒有變化日裙,才能更新庫存成功吹艇,如果版本號發(fā)生變化,則更新庫存失敗并進(jìn)行重試昂拂。

還有一些優(yōu)化比如
1.庫存放到redis等緩存中受神,在redis中進(jìn)行庫存的查詢、扣減格侯,利用內(nèi)存數(shù)據(jù)庫的特性提高讀QPS鼻听。
我當(dāng)前負(fù)責(zé)的一個應(yīng)用正是把庫存放在了內(nèi)存數(shù)據(jù)庫中來提高讀QPS财著,效果還是很顯著的
2.對DB進(jìn)行水平擴展(分庫分表方案)來提升讀寫QPS等等

根據(jù)經(jīng)驗:
大部分簡單業(yè)務(wù)場景下,方法1完全夠用了撑碴,甚至一些對并發(fā)并不是特別高撑教、業(yè)務(wù)容忍少量超賣場景下,直接扣庫存醉拓,無需檢查庫存是否stock-1 >= 0伟姐,但是要注意如果扣減庫存后,發(fā)現(xiàn)業(yè)務(wù)失敗亿卤,可能需要做恢復(fù)庫存操作愤兵。

四、如何驗證

最簡單粗暴的方法就是構(gòu)造大流量壓測:

1.第一個冪等問題排吴,對單用戶請求大流量壓測秆乳,基本都能發(fā)現(xiàn)問題。
2.第二個多用戶并發(fā)問題钻哩,多個用戶的請求大流量壓測屹堰,也能發(fā)現(xiàn)問題。

擴展下:
1個商品有多個庫存街氢,怎么處理扯键?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阳仔,隨后出現(xiàn)的幾起案子忧陪,更是在濱河造成了極大的恐慌扣泊,老刑警劉巖近范,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異延蟹,居然都是意外死亡评矩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門阱飘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斥杜,“玉大人,你說我怎么就攤上這事沥匈≌嵛梗” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵高帖,是天一觀的道長缰儿。 經(jīng)常有香客問我,道長散址,這世上最難降的妖魔是什么乖阵? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任宣赔,我火速辦了婚禮,結(jié)果婚禮上瞪浸,老公的妹妹穿的比我還像新娘儒将。我一直安慰自己,他們只是感情好对蒲,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布钩蚊。 她就那樣靜靜地躺著,像睡著了一般蹈矮。 火紅的嫁衣襯著肌膚如雪两疚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天含滴,我揣著相機與錄音诱渤,去河邊找鬼。 笑死谈况,一個胖子當(dāng)著我的面吹牛勺美,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碑韵,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼赡茸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祝闻?” 一聲冷哼從身側(cè)響起占卧,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎联喘,沒想到半個月后华蜒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡豁遭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年叭喜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓖谢。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡捂蕴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闪幽,到底是詐尸還是另有隱情啥辨,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布盯腌,位于F島的核電站溉知,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜着倾,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一拾酝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卡者,春花似錦蒿囤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恒傻,卻和暖如春脸侥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盈厘。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工睁枕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沸手。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓外遇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親契吉。 傳聞我的和親對象是個殘疾皇子跳仿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容