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


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
消息中间件 安全 PHP
PHP+Laravel+RabbitMQ实现异步延迟消息队列(库存归还)
一、前言 需求:电商秒杀场景中,如果用户下单10分钟未支付,需要进行库存归还 本篇是用PHP+Laravel+RabbitMQ来实现异步延迟消息队列
|
PHP 数据库 消息中间件
PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
如今在电商行业里,秒杀抢购活动已经是商家常用促销手段。但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题。 又比如:抢购火车票、论坛抢楼、抽奖乃至爆红微博评论等也会引发阻塞式高并发问题。如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?
2145 0
|
3月前
|
安全 关系型数据库 MySQL
PHP与MySQL交互:从入门到实践
【9月更文挑战第20天】在数字时代的浪潮中,掌握PHP与MySQL的互动成为了开发动态网站和应用程序的关键。本文将通过简明的语言和实例,引导你理解PHP如何与MySQL数据库进行对话,开启你的编程之旅。我们将从连接数据库开始,逐步深入到执行查询、处理结果,以及应对常见的挑战。无论你是初学者还是希望提升技能的开发者,这篇文章都将为你提供实用的知识和技巧。让我们一起探索PHP与MySQL交互的世界,解锁数据的力量!
|
3月前
|
NoSQL 关系型数据库 MySQL
不是 PHP 不行了,而是 MySQL 数据库扛不住啊
【9月更文挑战第8天】这段内容讨论了MySQL在某些场景下面临的挑战及其原因,并指出这些问题不能完全归咎于MySQL本身。高并发读写压力、数据量增长以及复杂查询和事务处理都可能导致性能瓶颈。然而,应用程序设计不合理、系统架构不佳以及其他数据库选择和优化策略不足也是重要因素。综合考虑这些方面才能有效解决性能问题,而MySQL通过不断改进和优化,仍然是许多应用场景中的可靠选择。
152 9
|
4月前
|
存储 SQL 关系型数据库
PHP与MySQL交互的奥秘
【8月更文挑战第29天】在编程的世界里,PHP和MySQL就像是一对默契的舞伴,共同演绎着数据的交响曲。本文将带你探索它们之间的互动,从连接数据库到执行查询,再到处理结果,每一步都充满了节奏与和谐。我们将一起走进这段代码的旅程,感受数据流动的魅力。
|
14天前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实践指南####
深入探索PHP与MySQL结合的魅力,本文旨在通过一系列实战案例,揭示如何高效构建动态交互式网站。从环境搭建到代码实现,全方位解析两者协同工作的原理与技巧,为开发者提供一条清晰的学习路径。 ####
|
19天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
34 1
|
24天前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发深度解析####
本文作为技术性文章,深入探讨了PHP与MySQL结合在动态网站开发中的应用实践,从环境搭建到具体案例实现,旨在为开发者提供一套详尽的实战指南。不同于常规摘要仅概述内容,本文将以“手把手”的教学方式,引导读者逐步构建一个功能完备的动态网站,涵盖前端用户界面设计、后端逻辑处理及数据库高效管理等关键环节,确保读者能够全面掌握PHP与MySQL在动态网站开发中的精髓。 ####
|
25天前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实战指南####
本文深入探讨了PHP与MySQL在动态网站开发中的应用实践,通过具体案例解析如何高效结合这两大技术构建数据驱动的Web应用。文章将涵盖环境搭建、基础语法回顾、数据库设计与操作、用户注册与登录系统实现等关键步骤,旨在为开发者提供一个从零到一的项目实战路径,展示PHP与MySQL协同工作的强大能力。 ####
|
2月前
|
SQL 关系型数据库 MySQL
PHP与MySQL协同工作的艺术:开发高效动态网站
在这个后端技术迅速迭代的时代,PHP和MySQL的组合仍然是创建动态网站和应用的主流选择之一。本文将带领读者深入理解PHP后端逻辑与MySQL数据库之间的协同工作方式,包括数据的检索、插入、更新和删除操作。文章将通过一系列实用的示例和最佳实践,揭示如何充分利用这两种技术的优势,构建高效、安全且易于维护的动态网站。