谷粒商城RabbitMQ锁库存逻辑详解--新理解(长文警告)
前言
不廢話,上來就說,代碼我會放挺多,寫過這個項目的自然能懂,如果真的像理解的請認真看哦
分析
/*出現的問題:扣減庫存成功了,但是由于網絡原因超時,出現異常,導致訂單事務回滾,庫存事務不回滾(解決方案:seata)為了保證高并發,不推薦使用seata,因為是加鎖,并行化,提升不了效率,可以發消息給庫存服務*/R r = wmsFeignService.orderLockStock(lockVo);if (r.getCode() == 0) {//鎖定成功responseVo.setOrder(order.getOrder());int i = 10/0;//注意這一行!!!!!!!!!!!!!!!!!!!!!!//TODO 訂單創建成功,發送消息給MQrabbitTemplate.convertAndSend("order-event-exchange","order.create.order",order.getOrder());//刪除購物車里的數據redisTemplate.delete(CART_PREFIX+memberResponseVo.getId());return responseVo;} else {//鎖定失敗String msg = (String) r.get("msg");throw new NoStockException(msg);// responseVo.setCode(3);// return responseVo;}上面的代碼是提交訂單那里的,請仔細看上面的邏輯,首先先遠程調用wmsFeignService.orderLockStock(lockVo),接下來讓我們看看這個方法
@PostMapping(value = "/lock/order")public R orderLockStock(@RequestBody WareSkuLockVo vo) {try {boolean lockStock = wareSkuService.orderLockStock(vo);return R.ok().setData(lockStock);} catch (NoStockException e) {return R.error(NO_STOCK_EXCEPTION.getCode(),NO_STOCK_EXCEPTION.getMessage());}}這是它的controller,它通過檢測下面的service方法看有沒有異常,有異常就return R.error
沒有就return R.ok
首先請注意異常拋出的地方
沒有任何倉庫有這個商品的庫存,當前商品所有倉庫都沒有鎖住,才會拋出異常!而拋出異常意味著,提交訂單(請看第一個代碼塊)那邊的 if (r.getCode() == 0) 這個判斷絕對會判斷失敗,從而走else邏輯,此時說明庫存根本沒鎖到(因為異常就是因為沒鎖到或沒庫存才拋出),所以根本不需要額外寫一個邏輯去判斷庫存需不需要解鎖,沒鎖還解鎖啥呀。
其次請注意鎖成功的話會發生什么
鎖成功就會向消息隊列發送“這個商品已經被鎖上了”的消息,延遲時間50min(在視頻里老師設置了2min以便觀察現象),請記住這個鎖倉庫成功的操作。此時 if (r.getCode() == 0) 這個判斷絕對為真,于是進入下面的邏輯
請注意,既然進入這個邏輯,說明鎖庫存沒拋異常,說明鎖成功了,那這里的 int i = 10/0 會導致這個方法出現異常。在沒有加入seata的時候,這整個方法只有非遠程方法可以回滾,加入seata后,在入口方法加入@GlobalTransactional,在從屬方法下加入@Transactional,可以做到全局回滾。
但是老師最后不用這個方法,他用了我之前發的一篇文章:
谷粒商城RabbitMQ設計思想詳解:消息隊列雙重保險設計
這種方法來實現解鎖庫存的操作,因為如果用seata會導致吞吐量下降嚴重。
下面我將描述解鎖庫存為什么不需要自己手動做
25號有個同學私信我說,在上面那張圖的else部分,無論成功還是失敗都往消息隊列發送消息,讓他判斷要不要解鎖庫存。我覺得可能是沒搞懂設計邏輯。
首先我們必須明確,解鎖庫存是在哪做的,在什么時候做的?
是在submitOrder這個方法完整執行后,用消息隊列監聽兩個死信隊列做的。
我怕大家忘記老師的設計模式,我再強調一次,老師實現的是最終一致性。
我給大家放一個圖片
你看,這么多分支情況,最終都會進入一個判斷“解不解鎖”的邏輯,大家應該聯系整個系統,在所有邏輯走到頭的情況下再個性化地添加不同的解鎖邏輯,如果像私信我的那個同學的解鎖,放在else塊里面,我覺得那個耦合度,應該有點大,而且很不方便維護,我是這樣覺得的哦
如果上面的圖片不夠清晰,那你可以試試下載這個
思維導圖…111
我不知道清晰度是不是一樣的…
我迫不得已才搞了個思維導圖,能想到的基本寫出來了,然后你如果做過項目,你思考一下,會發現老師基本把百分之90的情況搞定了,也就是大部分地方報錯,庫存那邊都能做到嚴密的自解鎖,可能中途有點一致性錯誤,不過既然是追求最終一致性,所以沒什么所謂。
尾聲
本次要分享的就是這些,我自認為寫的還算詳細,如果說錯了什么,或者有什么要討論的,大可以評論或者私信我,可以一起想哦
總結
以上是生活随笔為你收集整理的谷粒商城RabbitMQ锁库存逻辑详解--新理解(长文警告)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷粒商城RabbitMQ设计思想详解:消
- 下一篇: 《真三国无双》电影吕布曝光 造型神还原