問題描述:
庫存更新成負數java
產生緣由:
因爲多線程併發時每一個下單線程判斷是否超庫存時,讀到了數據庫一樣的值,都認爲庫存知足要求,都執行了下單扣庫存的操做,結果就是庫存被更新成了負數,實際下單量大於實際庫存。mysql
解決辦法:
一、能夠經過java的sychronized關鍵字以及Lock API去加鎖,這樣實現比較重,而且跨jvm的狀況須要考慮分佈式鎖。sql
二、在數據庫壓力不是特別大的狀況下,能夠有一個小技巧來快速解決問題:(TPS很大的狀況須要考慮消息隊列等方式)數據庫
在sql中加上條件,當前庫存>=n(要扣除的庫存)才執行更新,利用mysql執行更新時的鎖表機制,至關於用一條sql將庫存讀寫作成了原子化操做,若是update返回結果<1 ,則說明在執行update瞬間的庫存已經不足了多線程
update 商品庫存表 set stock=stock-1 where stock is not null and stock >=1 and id = goodsId
int r = updateBySqlString(sql.toString()); if(r<1){ //高併發下超量下單的問題 throw new BusinessException("庫存不足,請聯繫團長"); }
PS. 若是沒有索引,update會鎖表,若是加了索引,就會鎖行併發
安莫比科技jvm