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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: PHP处理库存超卖的几种处理方法

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

第一种方法:使用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 "没有库存了";
    }
}

第三种方法: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 '抢购失败!';
    }
}

第四种:文件排他锁方式


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);
}


相关文章
|
消息中间件 安全 PHP
PHP+Laravel+RabbitMQ实现异步延迟消息队列(库存归还)
一、前言 需求:电商秒杀场景中,如果用户下单10分钟未支付,需要进行库存归还 本篇是用PHP+Laravel+RabbitMQ来实现异步延迟消息队列
|
PHP 数据库 消息中间件
PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
如今在电商行业里,秒杀抢购活动已经是商家常用促销手段。但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题。 又比如:抢购火车票、论坛抢楼、抽奖乃至爆红微博评论等也会引发阻塞式高并发问题。如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?
2238 0
|
1月前
|
关系型数据库 MySQL PHP
PHP和Mysql前后端交互效果实现
本文介绍了使用PHP连接MySQL数据库的基本函数及其实现案例。内容涵盖数据库连接、选择数据库、执行查询、获取结果等常用操作,并通过用户登录和修改密码的功能实例,展示了PHP与MySQL的交互过程及代码实现。
183 0
PHP和Mysql前后端交互效果实现
|
6月前
|
关系型数据库 MySQL Linux
查看Linux、Apache、MySQL、PHP版本的技巧
以上就是查看Linux、Apache、MySQL、PHP版本信息的方法。希望这些信息能帮助你更好地理解和使用你的LAMP技术栈。
319 17
|
11月前
|
前端开发 关系型数据库 MySQL
PHP与MySQL动态网站开发实战指南####
【10月更文挑战第21天】 本文将深入浅出地探讨如何使用PHP与MySQL构建一个动态网站,从环境搭建到项目部署,全程实战演示。无论你是编程新手还是希望巩固Web开发技能的老手,都能在这篇文章中找到实用的技巧和启发。我们将一起探索如何通过PHP处理用户请求,利用MySQL存储数据,并最终呈现动态内容给用户,打造属于自己的在线平台。 ####
444 0
|
7月前
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
167 18
|
8月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
340 25
|
10月前
|
SQL 关系型数据库 MySQL
PHP与MySQL的高效交互:从基础到实践####
本文深入探讨了PHP与MySQL数据库之间的高效交互技术,涵盖了从基础连接到高级查询优化的全过程。不同于传统的摘要概述,这里我们直接以一段精简代码示例作为引子,展示如何在PHP中实现与MySQL的快速连接与简单查询,随后文章将围绕这一核心,逐步展开详细讲解,旨在为读者提供一个从入门到精通的实战指南。 ```php <?php // 数据库配置信息 $servername = "localhost"; $username = "root"; $password = "password"; $dbname = "test_db"; // 创建连接 $conn = new mysqli($se
278 31
|
11月前
|
安全 关系型数据库 MySQL
PHP与MySQL动态网站开发实战指南####
——深入探索LAMP栈下的高效数据交互与处理技巧 ####
|
11月前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实战指南####
深入探索PHP与MySQL的协同工作机制,本文旨在通过一系列实战案例,揭示构建高效、稳定且用户友好的动态网站的秘诀。从环境搭建到数据交互,再到最佳实践分享,本文为开发者提供了一条清晰的学习路径,助力其在LAMP(Linux, Apache, MySQL, PHP/Perl/Python)栈上实现技术飞跃。 ####
下一篇
开通oss服务