关键词搜索

源码搜索 ×
×

PHP处理库存超卖的几种处理方法???

发布1970-01-01浏览1166次

详情内容

第一种方法:使用mysql数据库的锁机制。在事务中使用 for update 语句,在事务处理完成之后释放这一条数据。

代码使用tp5的框架:

public function mysqlLock(){
    $goods_id = 26545;
    $sku_id = 26545;
    $price = 300;
    $user = '';
    StoreOrderModel::startTrans();
    $nums = StoreOrderModel::where(['id'=>1])->field('number')->lock(true)->find();
    $nums = $nums['number'];
    if($nums > 0){
        $item['goods_id'] = $goods_id;
        $item['sku_id'] = $sku_id;
        $item['number'] = $nums;
        $item['price'] = $price;
        $item['user'] = $user;
        $id = StoreModel::insertGetId($item);
        if($id){
            StoreOrderModel::where(['id'=>1])->setDec('number');
            StoreOrderModel::commit();
        }else{
            StoreOrderModel::rollback();
        }
    }else{
        echo "没有库存了";
    }
}

    第二种方法:redis 事务。

    public function start_reids_tran(){
        $goods_id = 26545;
        $sku_id = 26545;
        //$number = 1;
        $price = 300;
        $user = '';
        $redis = ResRedisModel::getinstance();
        $redis->watch('store');
        $nums = intval($redis->get('store'));
        if($nums > 0){
            $item['goods_id'] = $goods_id;
            $item['sku_id'] = $sku_id;
            $item['number'] = $nums;
            $item['price'] = $price;
            $item['user'] = $user;
            $redis->lPush('success', json_encode($item));
            $redis->multi();
            $redis->decr('store');
            $replies = $redis->exec(); // 执行以上 redis 事务
            if(!$replies){
                echo "订单 {$nums} 回滚".PHP_EOL;
            }
            $redis->unwatch();
            echo "抢购成功!".PHP_EOL;
        }else{
            echo "没有库存了";
        }
    }
    
      26
    • 27
    • 28

    第三种方法:redis 队列,预先把库存信息存入队列当中,抢购时判断队列的数量,然后出队。队列为空时库存为0。

    public function  eq_start(){
    
        $redis = ResRedisModel::getinstance();
        $nums = $redis->lSize('store');
        $goods_id = 26545;
        $sku_id = 26545;
        $number = 1;
        $price = 300;
        $user = '';
    
        if($nums > 0){
            $user = $redis->rPop('store');
            if($user){
                $item['goods_id'] = $goods_id;
                $item['sku_id'] = $sku_id;
                $item['number'] = $number;
                $item['price'] = $price;
                $item['user'] = $user;
                StoreModel::insertGetId($item);
                echo '抢购成功!';
            }else{
                echo '抢购失败!';
            }
        }else{
            echo '抢购失败!';
        }
    }
    
      26
    • 27

    第四种:文件排他锁方式

    public function file_star(){
    
        $fp = fopen('D:/phpStudy/PHPTutorial/www/public/lock.txt', "r");
    
        if(flock($fp, LOCK_EX)) { //排他型锁定 阻塞模式 , flock($fp,LOCK_EX | LOCK_NB) 非阻塞模式
    
            $nums = StoreOrderModel::where(['id'=>1])->field('number')->find();
            $nums = $nums['number'];
    
            if($nums > 0){
                $goods_id = 26545;
                $sku_id = 26545;
                $number = 1;
                $price = 300;
                $user = '213';
                $item['goods_id'] = $goods_id;
                $item['sku_id'] = $sku_id;
                $item['number'] = $number;
                $item['price'] = $price;
                $item['user'] = $user;
                StoreModel::insertGetId($item);
                StoreOrderModel::where(['id'=>1])->setDec('number');
                flock($fp, LOCK_UN); //释放锁定
                echo '抢购成功!';
            }else{
                echo '没有库存了!';
            }
        }else{
            echo '抢购失败!';
        }
        fclose($fp);
    }
    
      26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载