1. 程式人生 > >redis解決“高併發定時秒殺”庫存誤差問題

redis解決“高併發定時秒殺”庫存誤差問題

前言:高併發的秒殺活動中,通過查詢資料庫判斷是否還有庫存,然後對庫存欄位進行增減,極易出現庫存超出或者庫存為負的情況,一般來說有3中解決辦法(資料庫表加鎖,memche快取,redis佇列);

我們這裡使用redis來解決問題:

1、思路:

  1)觸發開始開團的同時,把庫存數量更新到id對應的佇列上去(定時更新,或者手動更新)

  2)使用者請求介面,如果佇列長度>0,移除一個佇列記錄,同時對資料庫進行相應操作

  3)如果佇列長度<=0,攔截使用者的訪問,返回‘無庫存’

 步驟:

1、後臺準點插入記錄到redis

$redis = get_redis(); 
// 1、資料庫獲取拼團資訊
$sql = "
select id,title,surplus_num,high_lines,ku_1,ku_2,ku_3,ku_4 from group_goods"; $arr = getrecord_array($sql); //2、刪除舊redis佇列 foreach ($arr as $key => $value) { //商品id $goods_id = $arr[$key]['id']; $redis->delete('acst_goods_high_lines'.$goods_id); } // 3、準點插入記錄到redis foreach ($arr as $key
=> $value) { //商品id $goods_id = $arr[$key]['id']; //庫存數量 $num = $arr[$key]['ku_3']; //json轉換 $in_list = json_encode($arr[$key]); for ($i=0; $i < $num; $i++) { $redis->lpush('acst_goods_high_lines'.$goods_id,$in_list); } }

2、客戶端搶購

$redis = get_redis(); 
//獲取佇列長度
$leng = $redis->lLen('acst_goods_high_lines'.$goods_id); if($leng>0){    //移除一條記錄 $redis->lpop('acst_goods_high_lines'.$goods_id); //減去庫存---增加成功開團數 $sql = "update group_goods set surplus_num = surplus_num-1,mtime = $t,success_num=success_num+20 where id = $goods_id limit 1"; exec_db($sql); }else{ echojson('已售罄,敬請期待',0); }