前言:高并发的秒杀活动中,通过查询数据库判断是否还有库存,然后对库存字段进行增减,极易出现库存超出或者库存为负的情况,一般来说有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); }