验证MySQL乐观锁与悲观锁并发情况

目标:验证谁更加能扛并发;

模拟场景,秒杀;

乐观锁实现

代码:

    //悲观锁扣库存
    public function test28(){
        /**
         * 1:查询库存数量
         * 2:判断是否可以购买(不可购买则退出循环)
         * 3:满足条件则减少对应库存,并记录拿到第多少个商品,提交并退出循环
         * 4:否则重试第1步
         */
        Db::startTrans();
        $i=1;
        do{
            $stock=TStock::where('id','=',1)->find();
            if ($stock->stock-1>=0){
                //有货
                //返回受影响条数
                $re=TStock::where('id','=',1)->where('stock','=',$stock->stock)->setDec('stock',1);
                if ($re===1){
                    //更新成功
                    TResult::insert(['value1'=>$stock->stock,'value2'=>$i]);//记录拿到第几个,第几次成功
                    Db::commit();
                    echo "第 $i 次成功!<br/>";
                    break;
                }else{
                    //更新失败---重试
                    echo "第 $i 次重试中.....<br/>";
                }
            }else{
                //没货了
                Db::rollback();
                echo "没货了<br/>";
                break;
            }
            $i++;
            if ($i>1000){
                echo '老子不要了,太难抢了!<br/>';
                Db::rollback();
                break;//高并发时候,乐观锁性能消耗巨大,改善:将消息加入队列处理
            }
        }while(true);
    }
ab测压结果:单纯乐观锁是个鸡肋

在这里插入图片描述
运行了好几次ab测压命令,才抢到15条,单纯乐观锁,基本没用,除非第一次就抢到,否者基本抢不到。就算配合消息队列处理,这也不是乐观锁本身扛并发了(难怪网上说成熟大网站才用乐观锁)。

悲观锁实现

    //悲观锁实现
    public function test29(){
        /**
         * 1:查询库存数量,并锁住记录
         * 2:判断是否可以购买(不可购买则退出)
         * 3:满足条件则减少对应库存,并记录拿到第多少个商品,提交
         */
        Db::startTrans();
        $stock=TStock::where('id','=',1)->lock(true)->find();
        if ($stock->stock-1>=0){
            TStock::where('id','=',1)->setDec('stock',1);
            TResult::insert(['value1'=>$stock->stock]);
            Db::commit();
            echo "买到第 $stock->stock 个!<br/>";
        }else{
            Db::rollback();
            echo '缺货<br/>';
        }
    }

测压命令

ab -n 260 -c 26 http://192.168.1.188:8042/index/test/test29

在这里插入图片描述

测压结果分析:90%的请求,都可以在1秒内完成。在库存充足情况下测试结果数据符合预期,库存不足时,ab测压工具经常报错(apr_socket_recv: 远程主机强迫关闭了一个现有的连接。 (730054))原因未知;

总结,正常情况下,还是悲观锁抗压

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值