昨天面試的時候,被面試官問到庫存扣減問題。。。估計面試官把我的專案當成秒殺了。。怪我自己沒介紹清楚專案,自己挖坑。。。
今天在部落格上看了一些關於庫存扣減問題,主要還是覺得比較合適的方式就是使用redis分布式鎖,這是最簡單的方案,但是如果事務過大,會有效能問題.操作不當,會有死鎖問題
如果兩個執行緒同時執行的話會出現超賣問題
所以我們要加個鎖
但這樣在併發量很高的時候,是不合適的,所以,可以考慮庫存占用
二、在redis中扣減庫存
innodb的行鎖特性其實是一把利與弊都同樣明顯的雙刃劍,在保證一致性的同時卻降低了可用性,那麼究竟應該如何保證大併發更新熱點資料不會導致資料庫淪為瓶頸,這其實是秒殺、搶購場景下最核心的技術難題之一。可以嘗試將熱賣商品的庫存扣減操作轉移至資料庫外,由於redis的讀/寫能力要遠勝過任何型別的關係型資料庫,因此在redis中實現庫存扣減將會是乙個不錯的替代方案,這樣一來,資料庫中儲存的商品庫存可以理解為實際庫存,而redis中儲存的商品庫存則為實時庫存。
1.先查詢redis中是否有庫存資訊,如果沒有就去資料庫查,這樣就可以減少訪問資料庫的次數。
2.獲取到後把數值填入redis,以商品id為key,數量為value。
`redistemplate.
opsforvalue()
.setifabsent
("key"
,"value"
);`
3.設定redis對應這個key的超時時間,以防所有商品庫存資料都在redis中。
redistemplate.
expire
("key"
,30000
, timeunit.milliseconds)
;
4.比較下單數量的大小,如果夠就做後續邏輯。
執行redis客戶端的increment,引數為負數,則做減法。因為redis是單執行緒處理,並且因為increment讓key對應的value 減少後返回的是修改後的值。
有的人會不做第一步查詢直接減,其實這樣不太好,因為當庫存為1時,很多做減3,或者減30情況,其實都是不夠,這樣就白減。
扣減資料庫的庫存,這個時候就不需要再select查詢,直接樂觀鎖update,把庫存欄位值減1 。
做完扣庫存就在訂單系統做下單。
5.釋放鎖
redistemplate.
delete
("key"
);
關於電商庫存扣減問題
b2c 庫存扣減方式 1 直接扣減實際庫存 直接採用實際庫存,每次客戶下單扣減實際庫存,容易導致庫存占用,對銷售和運營都不合理。a 如果購買使用者未付款,實際庫存導致庫存被扣減,讓有意願購買的使用者無從下單,對銷售業務有很大影響 b 未付款訂單給予30 40 鐘付款等待時間,未付款自動釋放虛擬銷售庫...
詭異的 庫存重複扣減 問題
業務場景 庫存扣減場景,消費方呼叫dubbo服務,扣減訂單的庫存 dubbo配置 5s超時時間,未配置預設重試次數 消費方 對商品加redis分布式鎖,防止併發扣減,失效與超時時間為10s 問題 使用者對相同商品的訂單,同時發起扣減庫存請求,造成了未扣減,或同一訂單多扣減的情況 疑惑 未扣減可能是失...
使用UpdLock來扣減庫存
updlock.updlock 的優點是允許您讀取資料 不阻塞其它事務 並在以後更新資料,同時確保自從上次讀取資料後資料沒有被更改。當我們用updlock來讀取記錄時可以對取到的記錄加上更新鎖,從而加上鎖的記錄在其它的執行緒中是不能更改的只能等本執行緒的事務結束後才能更改,更改庫存 begin tr...