高併發下減庫存操作避免超賣
阿新 • • 發佈:2019-01-05
在秒殺系統中,有100個請求過來下單,減庫存操作
方式一: for update 用時5504
select * from PPTEST.TBL_SHOP mm where ID=#{id,jdbcType=VARCHAR} for update
select for update這是資料庫行鎖,也是我們常用的悲觀鎖,可用於針對某商品的秒殺操作,但是當出現主鍵索引和非主鍵索引同時等待對方時,會造成資料庫死鎖
方式二:加鎖 用時9650
@Override
public void updateShop(String id,Integer num) {
try {
lock.lock();
ShopEntity entity = shopDao.getShop(id);
System.out.println("原數量是"+entity.getNum()+"我將對原數量減去" + num);
shopDao.updateShop(id,num);
entity = shopDao.getShop(id);
System.out.println("更新後的數量是"+entity.getNum());
}finally{
lock.unlock();
}
}
方式三:阻塞佇列 耗時2184
請求過來的時候放到固定大小的阻塞佇列,請求結束後或者秒殺時間結束後,遍歷佇列,做減操作,這需要顯示購買數量,因為100個請求不等於100個庫存
public void updateShop(String id,Integer num) {
ShopVO shopVO = new ShopVO();
shopVO.setNum(1);
shopVO.setId("1");
try {
queue.add(shopVO);
}catch (Exception e) {
System.out.println("該商品已經秒殺結束了奧!");
}
}
秒殺結束後執行的方法:
public void realUpdateShop() throws InterruptedException {
while(!queue.isEmpty()) {
ShopVO vo = queue.take();
System.out.println(vo.getNum());
shopDao.updateShop(vo.getId(),vo.getNum());
}
}