高併發下的下單功能設計

2021-07-25 16:56:41 字數 2566 閱讀 7535

商品表設計:熱銷商品提供給使用者秒殺,有初始庫存。

@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查詢了一次資料庫有沒有庫存,但是比較惡劣的情況是很多人都查到了有庫存,這個時候因為程式處理的延遲,沒有及時的減少庫存,那就出現了髒讀。如何在設計上避免呢?最笨的方法是對seckillcontrollerseckill方法做同步,每次只有乙個人能下單。但是太影響效能了,下單變成了同步操作。

@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....