使用redis隊列,因為pop操作是原子的,即使有很多用戶同時到達,也是依次執行,推薦使用


先將商品庫存如隊列

復制代碼
<?php
$store=1000;
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);
$res=$redis->llen('goods_store');
echo $res;
$count=$store-$res;
for($i=0;$i<$count;$i++){
    $redis->lpush('goods_store',1);
}
echo $redis->llen('goods_store');
復制代碼

搶購、描述邏輯

復制代碼
<?php
$conn=mysql_connect("localhost","big","123456"); 
if(!$conn){ 
    echo "connect failed"; 
    exit; 
} 
mysql_select_db("big",$conn); 
mysql_query("set names utf8");
 
$price=10;
$user_id=1;
$goods_id=1;
$sku_id=11;
$number=1;
 
//生成唯一訂單號
function build_order_no(){
  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//記錄日志
function insertLog($event,$type=0){
    global $conn;
    $sql="insert into ih_log(event,type) 
    values('$event','$type')"; 
    mysql_query($sql,$conn); 
}
 
//模擬下單操作
//下單前判斷redis隊列庫存量
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);
$count=$redis->lpop('goods_store');
if(!$count){
    insertLog('error:no store redis');
    return;
}
 
//生成訂單 
$order_sn=build_order_no();
$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 
values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 
$order_rs=mysql_query($sql,$conn); 
 
//庫存減少
$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
$store_rs=mysql_query($sql,$conn); 
if(mysql_affected_rows()){ 
    insertLog('庫存減少成功');
}else{ 
    insertLog('庫存減少失敗');
}
復制代碼

上述只是簡單模擬高並發下的搶購,真實場景要比這復雜很多,很多注意的地方

如搶購頁面做成靜態的,通過ajax調用接口

再如上面的會導致一個用戶搶多個,思路:

需要一個排隊隊列和搶購結果隊列及庫存隊列。高並發情況,先將用戶進入排隊隊列,用一個線程循環處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結果隊列,如果在,則已搶購,否則未搶購,庫存減1,寫數據庫,將用戶入結果隊列。

 
 


免責聲明!

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



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