>首页> IT >

PHP高并发实例详解之商品库存超卖并发测试

时间:2022-04-08 09:56:19       来源:转载
在之前的文章《PHP高并发实例详解之解决商品库存超卖问题》中,我们讲到了关于在高并发情况下防止商品库存超卖的相关问题,下面我们一起来看一下防止库存超卖之并发测试的相关内容,希望对大家有帮助。

推荐学习:《PHP学习教程》

基于《PHP高并发实例详解之解决商品库存超卖问题》的测试案例

一、 普通下单

并发测试时 product 表 id =1 name = 稻花香大米 store = 15

请求总数30 每次10个并发

ab -n 30 -c 10 http://xxxxx.top/code/the_limit/add_order.php

结果:

有 15 次库存减少成功 store 库存出现了负数 -7 8 次判断为库存不够 (库存负数是不正确的 不允许的)

二、unsigned 模式

调整回 product 表 id =1 name = 稻花香大米 store = 15

请求总数30 每次10个并发

ab -n 30 -c 10 http://xxxxx.top/code/the_limit/unsigned.php

结果:

有 15 次库存减少成功 store 库存出现了负数 -6 9 次判断为库存不够 (库存负数是不正确的 不允许的)

仅在查询语句上 加 for update 加锁效果不大

三、mysql 的事务,锁住操作的行

调整回 product 表 id =1 name = 稻花香大米 store = 15

请求总数30 每次10个并发

ab -n 30 -c 10 http://xxxxx.top/code/the_limit/ACID.php

结果:

有 15 次库存减少成功 store 库存未出现负数 15 次判断为库存不够 (库存负数是不正确的 不允许的)

加事务 效果不错 ab -n 3000 -c 1000 并发也能扛住

四、 非阻塞的文件排他锁

阻塞形式

非阻塞形式

效果也没有出现负数 但性能上 事务 > 阻塞 > 非阻塞

五、 redis 队列

代码与之前 略有调整 乐观锁版

connect("127.0.0.1", 6379);$redis->auth("PASSWORD");$redis->watch("sales");//乐观锁 监视作用 set()  初始值0$sales = $redis->get("sales");//var_dump($sales); exit;db();global $con;// 查询商品信息//$product_id = 1;//$sql = "select * from products where id={$product_id}";//$result = mysqli_query($con, $sql);//$row = mysqli_fetch_assoc($result);//$store = $row["store"];// 库存$n = 15;if ($sales >= $n) {    insertLog("库存为0 秒杀失败");    exit("秒杀结束");}//redis开启事务$redis->multi();$redis->incr("sales"); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。$res = $redis->exec(); //成功1 失败0if ($res) {    //秒杀成功    $con = new mysqli("localhost","root","PASSWORD","dev");    if (!$con) {        echo "数据库连接失败";    }    $product_id = 1;// 商品ID    $buy_num = 1;// 购买数量    sleep(1);    $sql = "update products set store=store-{$buy_num} where id={$product_id}";    if (mysqli_query($con, $sql)) {        echo "秒杀完成";        insertLog("恭喜 秒杀成功");    }} else {    insertLog("抱歉 秒杀失败");    exit("抢购失败");}function db(){    global $con;    $con = new mysqli("localhost","root","WOrd1234.*","dev");    if (!$con) {        echo "数据库连接失败";    }}/** * 记录日志 */function insertLog($content){    global $con;    $sql = "INSERT INTO `order_log` (content) values("$content")";    mysqli_query($con, $sql);}ab -n 30 -c 10 http://xxxxxx.top/code/the_limit/optimistic\ _redis_lock.php

最终结论 并发挑战 优先 redis 性能好

推荐学习:《PHP视频教程》

以上就是PHP高并发实例详解之商品库存超卖并发测试的详细内容,更多请关注php中文网其它相关文章!

关键词: 不正确的 数据库连接