一、初始方案
商品表設計:熱銷商品提供給用戶秒殺,有初始庫存。

秒殺訂單表設計:記錄秒殺成功的訂單情況:

Dao設計:主要就是一個減少庫存方法,其他CRUD使用JPA自帶的方法:

數據初始化以及提供保存訂單的操作:


下面就是controller層的設計:

上面是全部的基礎准備,下面使用一個單元測試方法,模擬高並發下,很多人來購買同一個熱門商品的情況。


訪問localhost:8080/simulationCocurrentTakeOrder,就可以測試了
預期情況:因為我們只對秒殺商品(123456)初始化了10件,理想情況當然是庫存減少到0,訂單表也只有10條記錄。
1、實際情況:訂單表記錄

2、商品表記錄

3、下面分析一下為啥會出現超庫存的情況:
因為多個請求訪問,僅僅是使用dao查詢了一次數據庫有沒有庫存,但是比較惡劣的情況是很多人都查到了有庫存,這個時候因為程序處理的延遲,沒有及時的減少庫存,那就出現了臟讀。如何在設計上避免呢?
最笨的方法是對SecKillController的seckill方法做同步,每次只有一個人能下單。但是太影響性能了,下單變成了同步操作。

二、改進方案
根據多線程編程的規范,提倡對共享資源加鎖,在最有可能出現並發爭搶的情況下加同步塊的思想。應該同一時刻只有一個線程去減少庫存。但是這里給出一個最好的方案,就是利用Oracle,MySQL的行級鎖–同一時間只有一個線程能夠操作同一行記錄,對SecKillGoodsDao進行改造:

僅僅是加了一個and,卻造成了很大的改變,返回int值代表的是影響的行數,對應到controller做出相應的判斷。

在看看運行情況

訂單表:

在高並發問題下的秒殺情況,即使存在網絡延時,也得到了保障。
擴展閱讀
來源:https://blog.csdn.net/u013815546/article/details/53928912