• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧
您的位置:首页 > CMS教程 >建站教程 > PHP高并发实例详解之解决商品库存超卖问题

PHP高并发实例详解之解决商品库存超卖问题

作者:站长图库 字体:[增加 减小] 来源:互联网

站长图库向大家介绍了PHP高并发实例,商品库存超卖问题等相关知识,希望对您有所帮助

本篇文章给大家带来了关于PHP的相关知识,其中主要介绍了关于在高并发情况下防止商品库存超卖的相关问题,主要解决高并发对数据库产生的压力以及竞争状态下如何解决商品库存超卖,希望对大家有帮助。


PHP高并发实例详解之解决商品库存超卖问题


商城系统中,抢购和秒杀是很常见的营销场景,在一定时间内有大量的用户访问商场下单,主要需要解决的问题有两个:

高并发对数据库产生的压力;

竞争状态下如何解决商品库存超卖;

高并发对数据库产生的压力

对于第一个问题,使用缓存来处理,避免直接操作数据库,例如使用 Redis。

竞争状态下如何解决商品库存超卖

对于第二个问题,需要重点说明。

常规写法:查询出对应商品的库存,判断库存数量否大于 0,然后执行生成订单等操作,但是在判断库存是否大于 0 处,如果在高并发下就会有问题,导致库存量出现负数。

测试表 sql

把如下表数据导入到数据库中

/*Navicat MySQL Data TransferSource Server         : 01 本地localhostSource Server Version : 50553Source Host           : localhost:3306Source Database       : testTarget Server Type    : MYSQLTarget Server Version : 50553File Encoding         : 65001Date: 2020-11-06 14:31:35*/SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for products-- ----------------------------DROP TABLE IF EXISTS `products`;CREATE TABLE `products` (  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',  `title` varchar(50) DEFAULT NULL COMMENT '货品名称',  `store` int(11) DEFAULT '0' COMMENT '货品库存',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='货品表';-- ------------------------------ Records of products-- ----------------------------INSERT INTO `products` VALUES ('1', '稻花香大米', '20');-- ------------------------------ Table structure for order_log-- ----------------------------DROP TABLE IF EXISTS `order_log`;CREATE TABLE `order_log` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `content` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '日志内容',  `c_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',  PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;-- ------------------------------ Table structure for order-- ----------------------------DROP TABLE IF EXISTS `order`;CREATE TABLE `order` (  `oid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '订单号',  `product_id` int(11) DEFAULT '0' COMMENT '商品ID',  `number` int(11) DEFAULT '0' COMMENT '购买数量',  `c_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',  PRIMARY KEY (`oid`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='订单表';


下单处理代码

<?phpdb();global $con;//step1 接收下单参数$product_id = 1;// 商品ID$buy_num = 1;// 购买数量//step2 查询商品信息$sql = "select * from products where id={$product_id}";$result = mysqli_query($con, $sql);$row = mysqli_fetch_assoc($result);//step3 判断商品下单数量是否大于商品库存数量//此处在高并发下,可能出现上一个下单后还没来得及更新库存,下一个下单判断库存数不是最新的库存if ($row['store'] > 0) {    sleep(1);    //step4 更新商品库存数量(减去下单数量)    $sql = "update products set store=store-{$buy_num} where id={$product_id}";    if (mysqli_query($con, $sql)) {        echo "更新成功";        //step5 生成订单号创建订单        $oid = build_order_no();        create_order($oid, $product_id, $buy_num);        insertLog('库存减少成功,下单成功');    } else {        echo "更新失败";        insertLog('库存减少失败');    }} else {    echo "没有库存";    insertLog('库存不够');}function db(){    global $con;    $con = new mysqli('localhost','root','root','test');    if (!$con) {        echo "数据库连接失败";    }}/** * 生成唯一订单号 */function build_order_no(){    return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);}function create_order($oid, $product_id, $number){    global $con;    $sql = "INSERT INTO `order` (oid, product_id, number) values('$oid', '$product_id', '$number')";    mysqli_query($con, $sql);}/** * 记录日志 */function insertLog($content){    global $con;    $sql = "INSERT INTO `order_log` (content) values('$content')";    mysqli_query($con, $sql);}


将库存字段字段设为 unsigned

因为库存字段不能为负数,在下单后更新商品库存时,如果出现负数将返回 false

<?phpdb();global $con;//step1 接收下单参数$product_id = 1;// 商品ID$buy_num = 1;// 购买数量//step2 查询商品信息$sql = "select * from products where id={$product_id} for UPDATE";//利用for update 开启行锁$result = mysqli_query($con, $sql);$row = mysqli_fetch_assoc($result);//step3 判断商品下单数量是否大于商品库存数量if ($row['store'] > 0) {    sleep(1);    //step4 更新商品库存数量(减去下单数量)    $sql = "update products set store=store-{$buy_num} where id={$product_
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • PHP高并发实例详解之解决商品库存超卖问题

相关文章

  • 一张图搞定如何在PhpStorm中修改类文件头部作者
  • 帝国CMS灵动标签显示标题属性、截取标题字数
  • 如何解决php方法执行时间过长的问题
  • PS绘制质感导航按钮
  • PHP中如何使用构造方法和this关键字?如何引入构造方法?
  • Photoshop打造快速坠入水的文字特效
  • Photoshop使用3D工具制作超酷的金属立体字
  • PHPcms v9安全教程:修改phpcms根目录下的phpcms目录名称
  • AI画笔工具在字体设计中的灵活运用
  • PS绘制苹果APP应用金属相机图标

文章分类

  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧

最近更新的内容

    • Photoshop制作冒气泡的透明艺术字教程
    • 手把手教你怎么在小程序中使用字体图标
    • 给dedecms软件列表页添加下载次数的方法
    • Photoshop制作简洁时尚的形象主页
    • 浅谈php正则替换函数preg_replace的用法
    • Photoshop设计复古风格的金属艺术字
    • Photoshop制作超酷现代战争按钮教程
    • 织梦DedeCMS实现按键盘方向键实现上一篇下一篇翻
    • Photoshop绘制任天堂Wii游戏手柄
    • 设计师应该从四个方面优化网站

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有