1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        京東二面:商品庫(kù)存的扣除過(guò)程,如何防止超賣(mài)?

        共 1181字,需瀏覽 3分鐘

         ·

        2022-02-21 17:42

        點(diǎn)擊“程序IT圈”,關(guān)注,置頂公眾號(hào)

        每日技術(shù)干貨,第一時(shí)間送達(dá)!


        在商品購(gòu)買(mǎi)的過(guò)程中,庫(kù)存的抵扣過(guò)程,一般操作如下:


        • select根據(jù)商品id查詢商品的庫(kù)存。

        • 根據(jù)下單的數(shù)量,計(jì)算庫(kù)存是否足夠,如果存庫(kù)不足則拋出庫(kù)存不足的異常,如果庫(kù)存足夠,則減去扣除的庫(kù)存得到最新的庫(kù)存剩余值。

        • set設(shè)置最新的庫(kù)存剩余值。


        上述過(guò)程的偽代碼如下:


        // 根據(jù)商品id獲取商品剩余庫(kù)存
        select?stock_remaing from?stock_table where?id=${goodsId};
        ?
        // 操作庫(kù)存
        // 比較庫(kù)存
        if(stock_remaing ???// 拋出庫(kù)存不足的異常
        }
        else{
        // 抵扣以后的庫(kù)存值
        int?new_stock=stock_remaing - quantity;
        }
        ?
        // 根據(jù)商品id設(shè)置計(jì)算后的庫(kù)存
        update stock_table set?stock_remaing =${new_stock} id=${goodsId};



        1

        并發(fā)修改數(shù)據(jù)庫(kù)存超賣(mài)


        如果數(shù)據(jù)庫(kù)事務(wù)的隔離級(jí)別不是串行化(serializable),根據(jù)事務(wù)的特性,在并發(fā)修改的時(shí)候,可能會(huì)出現(xiàn)寫(xiě)覆蓋的問(wèn)題。


        假設(shè),商品的剩余庫(kù)存stock_remaing 為100,客戶A下單20,客戶B下單30,在并發(fā)扣庫(kù)存的時(shí)候,可能存在超賣(mài)。如果客戶A和客戶B同時(shí)獲取剩余庫(kù)存為100,則會(huì)出現(xiàn)事務(wù)后提交的值會(huì)覆蓋前一個(gè)客戶提交的值,有可能剩余的庫(kù)存是80或者70。流程如下:




        2

        加鎖更新存庫(kù)


        為了在事務(wù)控制中,防止寫(xiě)覆蓋,你會(huì)想到使用select for update的方式,將該商品的庫(kù)存鎖住,然后執(zhí)行余下的操作。


        流程如下:



        以上,使用悲觀鎖方式,在分布式服務(wù)中,如果并發(fā)情況比較高的時(shí)候,扣減庫(kù)存的操作是串行操作,效率很低。



        3

        使用樂(lè)觀鎖的方式更新


        在更新的時(shí)候,使用(CAS+版本號(hào)更新)+重試條件(重試次數(shù)或者重試時(shí)間限制)樂(lè)觀鎖的方式更新庫(kù)存。此時(shí),如果,客戶A和客戶B同時(shí)讀取到庫(kù)存剩余100,在更新的時(shí)候,有一個(gè)操作會(huì)失敗。流程如下:



        該種方式可以大大提高并發(fā)性,也可以保證數(shù)據(jù)的一致性;通過(guò)重試次數(shù)和重試時(shí)間的條件控制,可以防止過(guò)多的重試帶來(lái)的數(shù)據(jù)庫(kù)壓力。微信搜索公眾號(hào):Java后端編程,回復(fù):java 領(lǐng)取資料 。



        4

        可以使用直接遞減的方式執(zhí)行么?


        在抵扣庫(kù)存的時(shí)候,有的人提議不執(zhí)行select,計(jì)算,set三段式的操作,直接扣減的方式,并且對(duì)于扣減到小于零的情況作了判斷。偽代碼如下:


        update?stock_table set?remaing_stock=remaing_stock-${quantity}
        where?id?=商品id
        and?remaing_stock>${quantity};


        在分布式服務(wù)調(diào)用中,因?yàn)榫W(wǎng)絡(luò)異常,獲取服務(wù)器異常,可能在微服務(wù)調(diào)用時(shí),存在服務(wù)重試。例如,場(chǎng)景的網(wǎng)關(guān)超時(shí),服務(wù)重試機(jī)制。此時(shí),該種方式不滿足冪等性,而存在多扣的情況。例如,同一用戶扣減庫(kù)存時(shí),服務(wù)重試,極端情況下,該用戶扣減庫(kù)存操作執(zhí)行多次,則就出現(xiàn)了商品超賣(mài)。



        5

        可以使用redis進(jìn)行庫(kù)存的抵扣么?


        由于沒(méi)有研究過(guò)redis源碼,對(duì)于這種方式參考了大牛的回復(fù),答案是可以使用redis的事務(wù)性扣減余額,但在CAS機(jī)制上比mysql沒(méi)有優(yōu)勢(shì),高性能是因?yàn)槠鋬?nèi)存存儲(chǔ)的原因,帶來(lái)的副作用是數(shù)據(jù)有丟失風(fēng)險(xiǎn)。


        來(lái)源:blog.csdn.net/new_com/article/details/105568124


        PS:防止找不到本篇文章,可以收藏點(diǎn)贊,方便翻閱查找哦。?


        (完)

        PS:如果覺(jué)得我的分享不錯(cuò),歡迎大家隨手點(diǎn)贊、在看。

        ?關(guān)注公眾號(hào):Java后端編程,回復(fù)下面關(guān)鍵字?


        要Java學(xué)習(xí)完整路線,回復(fù)??路線?

        缺Java入門(mén)視頻,回復(fù)?視頻?

        要Java面試經(jīng)驗(yàn),回復(fù)??面試?

        缺Java項(xiàng)目,回復(fù):?項(xiàng)目?

        進(jìn)Java粉絲群:?加群?


        PS:如果覺(jué)得我的分享不錯(cuò),歡迎大家隨手點(diǎn)贊、在看。

        (完)




        加我"微信"?獲取一份 最新Java面試題資料

        請(qǐng)備注:666,不然不通過(guò)~


        最近好文


        1、再見(jiàn)了,收費(fèi)的XShell,我改用國(guó)產(chǎn)良心工具!

        2、給IDEA換個(gè)酷炫的主題,真的太好看了!

        3、SpringBoot快速開(kāi)發(fā)利器:Spring Boot CLI

        4、基于SpringBoot 的CMS系統(tǒng),拿去開(kāi)發(fā)企業(yè)官網(wǎng)

        5、本機(jī)號(hào)碼一鍵登錄原理與應(yīng)用



        最近面試BAT,整理一份面試資料Java面試BAT通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
        獲取方式:關(guān)注公眾號(hào)并回復(fù)?java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
        明天見(jiàn)(??ω??)??
        瀏覽 27
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久久九九女女男热 | 淫色一非一区二区朝鲜 | 狠狠色噜噜狠狠狠7777奇米 | 国产区欧美 | 午夜激情一区 | 婷婷五月六月丁香 | 丰满的少妇中文版2023 | 蜜臀久久99精品久久久兰草影视 | 国产精品久久久久影院老司 | 亚洲AV蜜桃永久无码精品性色 |