商品表設計:熱銷商品提供給使用者秒殺,有初始庫存。
@entity
public
class
seckillgoods
implements
serializable
秒殺訂單表設計:記錄秒殺成功的訂單情況
@entity
public
class
seckillorder
implements
serializable
dao設計:主要就是乙個減少庫存方法,其他crud使用jpa自帶的方法
public
inte***ce
seckillgoodsdao
extends
jparepository
資料初始化以及提供儲存訂單的操作:
@service
public
class
seckillservice
/*** 購買成功,儲存訂單
*@param consumer
*@param goodsid
*@param num
*/public
void
generateorder(string consumer, string goodsid, integer num)
}
下面就是controller層的設計
@controller
public
class
seckillcontroller
return
"購買失敗,庫存不足";}}
上面是全部的基礎準備,下面使用乙個單元測試方法,模擬高併發下,很多人來購買同乙個熱門商品的情況。
@controller
public
class
seckillsimulationopcontroller
system.out.println(consumername+":"+result);
} catch (exception e)
}}).start();
}return
"simulationcocurrenttakeorder";}}
訪問localhost:8080/simulationcocurrenttakeorder,就可以測試了
預期情況:因為我們只對秒殺商品(123456)初始化了10件,理想情況當然是庫存減少到0,訂單表也只有10條記錄。
實際情況:訂單表記錄
商品表記錄
下面分析一下為啥會出現超庫存的情況:
因為多個請求訪問,僅僅是使用dao查詢了一次資料庫有沒有庫存,但是比較惡劣的情況是很多人都查到了有庫存,這個時候因為程式處理的延遲,沒有及時的減少庫存,那就出現了髒讀。如何在設計上避免呢?最笨的方法是對seckillcontroller
的seckill
方法做同步,每次只有乙個人能下單。但是太影響效能了,下單變成了同步操作。
@responsebody
public
synchronized string seckill
根據多執行緒程式設計的規範,提倡對共享資源加鎖,在最有可能出現併發爭搶的情況下加同步塊的思想。應該同一時刻只有乙個執行緒去減少庫存。但是這裡給出乙個最好的方案,就是利用oracle,mysql的行級鎖–同一時間只有乙個執行緒能夠操作同一行記錄,對seckillgoodsdao
進行改造:
public
inte***ce
seckillgoodsdao
extends
jparepository
僅僅是加了乙個and,卻造成了很大的改變,返回int值代表的是影響的行數,對應到controller做出相應的判斷。
@responsebody
public string seckill(string consumer,string goodsid,integer num) throws interruptedexception else
}else
}return
"購買失敗,庫存不足";
}在看看運**況
訂單表:
在高併發問題下的秒殺情況,即使存在網路延時,也得到了保障。
高併發下的HashMap
1.hashmap在插入元素過多的時候需要進行resize,resize的條件是 hashmap.size capacity loadfactor。2.hashmap的resize包含擴容和rehash兩個步驟,rehash在併發的情況下可能會形成鍊錶環 hashmap進行儲存時,假設size超過當...
高併發下的MySQL
對於遊戲來說,db存在大量的insert update 可謂玩家的很多動作都會與db溝通。本文暫時忽略os 中的 io利用率,網絡卡流量,cpu變化情況,介紹如何檢視mysql部分引數 檢視每秒事務數 show global status like com commit show global st...
redis實現高併發下的搶購 秒殺功能
常規寫法 查詢出對應商品的庫存,看是否大於0,然後執行生成訂單等操作,但是在判斷庫存是否大於0處,如果在高併發下就會有問題,導致庫存量出現負數 redis的解決方案 1,inlcude oncea include db.php redis new redis resid connect 127.0....