用redis做一个简单的秒杀
2016-11-14 16:36
344 查看
下面是一个简单的下单操作;
<?php include "MMysql.class.php"; $configArr=[ 'host'=>, 'port'=>, 'user'=>, 'passwd'=>, 'dbname'=>, ]; $db = new MMysql($configArr); $sql="select * from sdb_b2c_products where product_id='38'"; $product=$db->doSql($sql); if(!$product){ echo "error:not find product"; return; } $product=$product[0]; if($product['store']-$product['freez']<1){ echo "error:no store"; return; } $sql="select * from sdb_b2c_member_addrs where member_id='256187'"; $addr=$db->doSql($sql); $addr=$addr[0]; $data=[ 'order_id'=>date('ymdHis').rand(100,999), 'total_amount'=>$product['price'], 'final_amount'=>$product['price'], 'pay_status'=>'0', 'createtime'=>time(), 'shipping_id'=>'13', 'shipping'=>'韵达', 'member_id'=>'636389', 'ship_area'=>$addr['area'], 'shipname'=>$addr['name'], 'ship_addr'=>$addr['addr'], ]; $order=$db->insert('sdb_b2c_orders',$data); if($order){ $sql="update sdb_b2c_products set freez=freez+1 where product_id='38'"; $db->doSql($sql); echo "order create success"; return; }else{ echo "error:order create fail"; return; } ?>代码解释为:在商品表中找到商品,获取实际库存和虚拟库存,如果时间库存减去虚拟库存小于1,则表示没有库存了如果有实际库存,则去找memeber_id为'256187' 的会员收货地址信息,然后创建订单如果订单创建成功,则更新虚拟库存。用jmeter测试了在并发下的效果,设置500个线程去模拟并发测试前设置实际库存store为50,虚拟库存freez为0,正常情况下freez只能达到50,否则就会有超卖的情况实际测试,在高并发的情况下freez通常都大于50,在54左右。由于获取库存是否还有,到更改库存中间有一定的时间差,所有高并发下会出现超卖的问题。 下面的代码经过修改,使用redis的list作为队列。<?php$store=50;$redis=new Redis();$result=$redis->connect('127.0.0.1',6379);$res=$redis->llen('pro38');echo $res;$count=$store-$res;for($i=0;$i<$count;$i++){ $redis->lpush('pro38',1);}echo $redis->llen('pro38');?>上面是添加一个库存为50的redis的list下面贴上下单代码<?phpinclude "MMysql.class.php";$configArr=[ 'host'=>'121.41.38.44', 'port'=>'3306', 'user'=>'yuancheng', 'passwd'=>'yuancheng', 'dbname'=>'laiyifendb',];$db = new MMysql($configArr);$redis=new Redis();$result=$redis->connect('127.0.0.1',6379);$count=$redis->lpop('pro38');if(!$count){ echo "error:no store redis"; return;}$sql="select * from sdb_b2c_products where product_id='38'";$product=$db->doSql($sql);if(!$product){ echo "error:not find product"; return;}$product=$product[0];if($product['store']-$product['freez']<1){ echo "error:no store"; return;}$sql="select * from sdb_b2c_member_addrs where member_id='256187'";$addr=$db->doSql($sql);$addr=$addr[0];$data=[ 'order_id'=>date('ymdHis').rand(100,999), 'total_amount'=>$product['price'], 'final_amount'=>$product['price'], 'pay_status'=>'0', 'createtime'=>time(), 'shipping_id'=>'13', 'shipping'=>'韵达', 'member_id'=>'636389', 'ship_area'=>$addr['area'], 'shipname'=>$addr['name'], 'ship_addr'=>$addr['addr'],];$order=$db->insert('sdb_b2c_orders',$data);if($order){ $sql="update sdb_b2c_products set freez=freez+1 where product_id='38'"; $db->doSql($sql); echo "order create success"; return;}else{ echo "error:order create fail"; return;}?>
经过测试,此方法可以防止超卖的发生
相关文章推荐
- 用redis做一个简单的秒杀
- 用redis做一个简单的秒杀
- 简单的redis使用watch完成秒杀抢购功能
- 使用redis写一个简单的分布式锁
- 记录搭建redis用作缓存并且成功运行了一个简单例子的经历
- 演示一个简单的Redis队列
- 单台服务器redis的简单秒杀
- 一个简单的log4j2的redis appender ,依赖于Jedis (A simple log4j2 redis appender which uses Jedis)
- 用.netcore写一个简单redis驱动,调试windows版本的redis
- Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境
- 一个简单的Redis应用(修订版)
- 用redis 做一个简单的 pub / sub 系统
- 用.netcore写一个简单redis驱动,调试windows版本的redis.平且给set和get命令添加参数.
- 简单实现了一个基于redis的分布式锁,存在bug...
- 一个Lua脚本操作Redis的简单例子
- 用redis来实现Session保存的一个简单Demo
- redis_简单秒杀_watch事务
- Python使用Redis实现一个简单作业调度系统
- redis_简单秒杀
- Redis的一个简单连接池