thinkphp高並發搶購代碼測試-解決高並發下的超賣問題!


下面測試2種搶購實現方案

首先數據庫中一個很簡單的表

DROP TABLE IF EXISTS `op_qiang`;
CREATE TABLE `op_qiang` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `num` int(8) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `op_qiang` (`id`, `num`) VALUES
(1,	10);
op_qiang這個表中 ID為1的商品 庫存數量為10

第一種方案 將mysql中,num這個字段 設置為 unsigned 表示這個字段不能為負數,如果減庫存為負數了就會返回flase總而解決超賣問題。

//搶購 通過 mysql 字段設置 設為unsigned, 實現

public function sqla(){
  $f = db('qiang')->where('id',1)->find();
  $t = mt_rand(100,999999);
  if($f['num']<=0){
    exit("over");
  }
  $re = db('qiang')->where('id',1)->setDec('num',1);
  if($re){

    //模擬搶到了的客戶,寫入操作邏輯
    file_put_contents('log.txt',$t."---ok\r\n",FILE_APPEND);
  }else{
    file_put_contents('log.txt',$t."--\r\n",FILE_APPEND);
  }
}

用ab模擬測試, ab -r -n 1000 -c 500  http://192.168.1.112/index.php/index/index/sqla  代碼運行正常!

 

下面用redis測試

//首先redis中將庫存加入隊列,

public function dos()
{
  $redis = new \Redis();
  $redis->connect('127.0.0.1', 6379);//serverip port
  $count = 10;//redis中加入 列表 的數量  表示庫存
  $res=$redis->llen('goods_store');
  echo $res;

  for($i=0;$i<$count;$i++){
    $redis->lpush('goods_store',1);
  }
  echo $redis->llen('goods_store');
}

//搶購環節 讀取隊列,隊列沒有了,表示搶購已經完成,沒有庫存了

public function sqlb(){
  $redis = new \Redis();
  $redis->connect('127.0.0.1', 6379);//serverip port
  $count=$redis->lpop('goods_store');
  echo $count;
  if(!$count){
    exit("over");
  }
  $re = db('qiang')->where('id',1)->setDec('num',1);//減庫存


}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM