国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

商品超賣問題

2019-11-14 14:54:41
字體:
供稿:網(wǎng)友

背景

在公司里面我負(fù)責(zé)的是積分商城一塊,里面的積分商品也跟其它商品一樣,超賣是絕對不可以的。。。。


剛接手到積分商城

我剛來的時候,積分商城已經(jīng)有了自家優(yōu)惠券的功能,整個商城就2件商品:滿5減1+滿10減2.
我要做的第一個功能就是添加新的功能:第三方優(yōu)惠券(其實就是跟我餓了么什么的一樣啦)。自家的優(yōu)惠券是通過模版生成的,給用戶一個兌換碼;第三方優(yōu)惠券是從數(shù)據(jù)庫里拿的(第三方給的),同樣是給用戶一個兌換碼。
具體實現(xiàn)的思路就是:找到這個商品,然后通過這個商品的某個字段來找到對應(yīng)的兌換碼,這里的兌換碼會有很多,那么給他一張就行了。發(fā)兌換碼肯定是分為2步的:1.從庫里面取一張,2.將取出的這一張狀態(tài)標(biāo)記為已使用。這里會出現(xiàn)一個問題,并發(fā)的情況下,也就是1.2步之間如果打個斷點,那么2個人會得到相同的一張兌換碼,而且第二次update的時候是對數(shù)據(jù)庫沒有影響的。
這里的解決方法就有很多了:

1.sql不怕累的:來個存儲過程;2.java不怕累的:根據(jù)update返回的結(jié)果是1還是0(有沒有有效的update),來各種判斷各種處理;3.不怕慢的:把2個操作放在同一個事務(wù)里面,,其實我最早的想法就是這樣的,因為以前做項目沒啥效率要求,我也一直覺得這樣很好。但是我們公司的讀寫是分離的,從代碼里面就能看到讀的slave是不帶事務(wù)的,至于他們使用的是否為同一個數(shù)據(jù)庫,還得看生產(chǎn)環(huán)境上怎么配。當(dāng)時我就想把這里讀的那個也換成master來,然后加個事務(wù),這樣基本就可以了。但是帶我的那個非常不滿意,表示如果把讀加上了事務(wù)會非常的慢,所以被否定了。?!,F(xiàn)在想想也是有些道理,這個能否實現(xiàn)還得看事務(wù)隔離級別的設(shè)置,而隔離級別要是滿足了說不定運行起來還真的阻塞的哭了。。4.最終的實現(xiàn)方案:我們最后用的是redis,所有的優(yōu)惠券統(tǒng)一從redis中取,如果redis中沒有,那就一次性從數(shù)據(jù)庫中拿出5條來。使用了這個方法,讓我對redis的了解多了不少。后面商品修改的時候,由于redis中的緩存也讓我吃了不少苦---就是找不到問題所在,最后發(fā)現(xiàn)原來問題出在緩存沒清。。。

小結(jié)

第三方優(yōu)惠券的處理方案:把優(yōu)惠券放倒緩存中,然后統(tǒng)一從緩存中取。


后來商城的搶購活動

第三方提供了10件襯衫,要求我們搞個搶購。
當(dāng)時給的時間也不多,也沒準(zhǔn)備改啥代碼,就插了10條數(shù)據(jù)到第三方兌換券的數(shù)據(jù)庫,把襯衫當(dāng)做第三方優(yōu)惠券來看,然后最后哪10個人搶到了再從兌換記錄里面找。
之前用redis處理了并發(fā)的問題,所以對于這個搶購還是比較自信的。。最終也是沒有出現(xiàn)問題。


v3.0要求添加抽獎功能

也就是后天要上線的新功能,這兩天可把我給忙壞了;當(dāng)時聽到要添加抽獎功能的消息時,可把我給高興壞了,可有好玩的東西寫了。
當(dāng)時腦袋里浮現(xiàn)出來的就是各種貴重物品抽抽抽,產(chǎn)品也說到時候抽iphone啥的。
這個可千萬要小心,抽獎這事可別抽1個iphone搞出10個同時中獎來。。。
我的想法時這樣的:

第三方券能夠通過實實在在存在的券來控制,而其它的東西,沒有實際存在的券,該怎么實現(xiàn)并發(fā)不出問題呢?第一個想法還是用緩存,這次把商品的剩余數(shù)量給放到redis中來,把分布式的并發(fā)交給redis來處理,每次get and 減一 嘛。這個功能redis里好像是有,但是在sPRing-data的redis封裝里面我沒找到對應(yīng)的方法。

于是我就想去找找以前的自家優(yōu)惠券是怎么寫的,怎么控制不超買的,因為這個通過模版生成的東西也是通過商品的剩余數(shù)量來控制的,也并沒有實際存在的券。
代碼看完了,也沒發(fā)現(xiàn)哪里控制了并發(fā),更沒發(fā)現(xiàn)哪里用到了緩存。
喜出望外,為啥?因為我發(fā)現(xiàn)了帶我的人代碼的問題,終于可以修復(fù)一下他的代碼來展現(xiàn)一下自己了。
于是我去網(wǎng)上搜有關(guān) 搶購超賣 的處理方案,基本上就是

1.緩存,就是我上面說的2.消息隊列,應(yīng)該就是序列化吧,別搶,都給我排隊去3.存儲過程,我都懶得看。因為我知道我看明白了我也懶得寫那么長的sql的4.update table set a=a-1 where a>=1 and id =x ,行鎖

這里我選擇了第4中方法,因為帶我的人說,不需要用緩存,使用sql就能完成,有行鎖。
網(wǎng)上的說法是,請求量很大的時候行鎖會使數(shù)據(jù)庫壓力非常大。我也覺得很有道理,不過想想我們積分商城的訪問量,就先用這個簡單的把,哪天訪問量吃不消的,讓我改成緩存我也樂意。


一頓改

翻了一下原來的代碼,發(fā)現(xiàn)并發(fā)是肯定會出問題的,為此我還測試了下,打了個斷點,的確出問題了。
之前的sql是這樣寫的:

update table set a=a-1 where id =x

然后剩余數(shù)量這字段還是unsigned的,所以報了out of range的錯,這明顯就是要超賣,而數(shù)據(jù)庫缺報錯了,不過2個用戶都提示兌換成功了。。
sql改了后,還是有問題,為啥,因為返回值沒用上啊。
之前的剩余數(shù)量可以說就是用來標(biāo)記一下還有多少個,用來平常用用的。
現(xiàn)在我把它提到了方法的第一行,判斷返回值是否為0,多了一個處理并發(fā)的功能。

小結(jié)

簡單處理并發(fā):

update table set a=a-1 where a>=1 and id =x根據(jù)返回結(jié)果來看,如果為0,表示賣完了。不為0再繼續(xù)下面的操作

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 泾源县| 长海县| 工布江达县| 乐至县| 乡宁县| 年辖:市辖区| 保山市| 浮梁县| 图木舒克市| 扶余县| 曲沃县| 合阳县| 会同县| 莱阳市| 绥中县| 体育| 乃东县| 福州市| 清河县| 齐齐哈尔市| 卓资县| 新泰市| 万源市| 台东市| 和龙市| 鄂托克前旗| 怀化市| 永春县| 运城市| 青冈县| 五原县| 许昌县| 彭泽县| 晋宁县| 临海市| 广元市| 达孜县| 达孜县| 遵义市| 伊川县| 凤翔县|