php+redis抢购商品高并发实现

 1、准备前库存先存储到redis

// 创建Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379); // 假设Redis服务器在本地运行,端口为默认的6379
// 商品ID
$productID = 123;
//库存
$stock=10;
$stockKey = 'product:' . $productID . ':stock';
$redis->set($stockKey,$stock);

2、用户抢购 

// 创建Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379); // 假设Redis服务器在本地运行,端口为默认的6379
// 商品ID
$productID = 123;
// 检查并发数控制
$maxConcurrent = 10; // 设置最大并发数为10
if ($redis->incr('concurrent_users') > $maxConcurrent) {$redis->decr('concurrent_users');die('抢购过于火爆,请稍后再试!');
}
// 检查抢购有效性
if ($redis->sismember('purchased_users:' . $productID, '用户ID')) {$redis->decr('concurrent_users');die('您已经购买过该商品!');
}
// 检查库存
$stockKey = 'product:' . $productID . ':stock';
$currentStock = $redis->get($stockKey);
if ($currentStock <= 0) {$redis->decr('concurrent_users');die('商品库存不足!');
}
// 扣减库存
$redis->decr($stockKey);
$redis->sadd('purchased_users:' . $productID, '用户ID');
// 抢购成功,进行后续操作
// ...
// 记录抢购日志
$logEntry = '用户ID 抢购了商品ID:' . $productID . ' ' . date('Y-m-d H:i:s');
$redis->rpush('purchase_log', $logEntry);
// 释放并发数控制
$redis->decr('concurrent_users');
echo '抢购成功!';

 

  1. 创建Redis连接:首先,你需要在PHP代码中创建一个与Redis服务器的连接。可以使用现有的Redis扩展或包来实现。
  2. 加载商品信息到Redis缓存:在抢购开始之前,你可以将商品的信息加载到Redis缓存中。这可以减轻数据库的负担,并提高读取速度。你可以使用Redis的哈希表数据结构来存储商品的ID、名称、库存等信息。
  3. 控制抢购并发数:为了避免超卖和数据不一致的问题,你需要限制抢购的并发数。可以使用Redis的原子性操作,如INCRDECR命令,来实现原子的并发数控制。例如,你可以使用一个Redis计数器来记录当前正在进行抢购的用户数。如果超过了设置的并发限制,可以返回错误或给用户一个友好的提示。
  4. 有效性检查:在用户发起抢购请求之前,进行一些有效性检查是很重要的,例如检查用户是否已经达到抢购次数的限制,或者是否已经购买过该商品。这些检查可以在Redis缓存中进行,以减少数据库查询的频率。
  5. 扣减库存:在用户成功抢购之后,需要扣减商品的库存。你可以使用Redis的原子性操作,如DECRBY命令,在多个并发请求下准确地扣减库存。如果库存不足,可以返回错误或给用户一个友好的提示。
  6. 记录抢购日志:为了跟踪和统计抢购活动,可以使用Redis的列表数据结构来记录抢购日志。每次抢购成功可以将相关信息写入到Redis的一个列表中,后续可以根据需要对日志进行处理和分析。 请注意,上述步骤中的一些操作可以在数据库层面或Redis层面进行,具体取决于你的系统架构和需求。使用Redis作为缓存的好处是可以提高读取速度和并发处理能力,减轻了数据库的负担

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Notepad++批量添加引号

工作中经常会遇到这样情景&#xff1a;业务给到一批订单号&#xff0c;需要查询这批订单的某些字段信息。在where条件中需要传入这些订单号的数组&#xff0c;并且订单号用引号引起&#xff0c;用引号隔开。 字符串之间长度相同 可以按住CtrlAlt和鼠标左键选中区域&#xff0…

ora.LISTENER.lsnr状态为Not All Endpoints Registered

客户的监控反馈有个监听无法连接&#xff0c;登录环境检查发现ora.LISTENER.lsnr的状态为Not All Endpoints Registered&#xff0c;如下 [rootdb2 ~]# crsctl status res -t -------------------------------------------------------------------------------- NAME …

C/C++内存管理(含C++中new和delete的使用)

文章目录 C/C内存管理&#xff08;含C中new和delete的使用&#xff09;1、C/C内存分布2、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3、C动态内存管理3.1、new/delete操作内置类型3.2、new/delete操作自定义类型 4、operator new与operator delete函数5、…

Jave内存模型 与 CPU硬件架构 的交互图

JMM里所讲的主内存、工作内存与Java内存区域中的Java堆、栈、方法区等并不是同一个层次的对内存的划分&#xff0c;这两者基本上是没有任何关系的。 如果两者一定要勉强对应起来&#xff0c;那么从变量、主内存、工作内存的定义来看&#xff0c;主内存主要对应于Java堆中的对象…

Git分支合并导致文件异常

昨天合并分支后&#xff0c;突然出现了项目中全部的文件出现异常。 先说结论&#xff1a;合并导致文件冲突处理异常&#xff0c;Git lfs 异常 解决方式&#xff1a;CMD 中执行 git lfs install git lfs pull。 合并分支后&#xff0c;发现项目中全部的png异常&#xff0c;编译a…

【华为交换】交换机聚合接口配置(Eth-trunk)

功能简介 Eth-Trunk又叫以太网链路聚合Eth-Trunk&#xff0c;它通过将多条以太网物理链路捆绑在一起成为一条逻辑链路。达到增加链路带宽的目的。在实现增大带宽目的的同时&#xff0c;Eth-Trunk采用备份链路的机制&#xff0c;可以有效的提高设备之间链路的可靠性。每个聚合组…

[原创][2]探究C#多线程开发细节-”线程的无顺序性“

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delph…

[PyTorch][chapter 3][李宏毅深度学习-偏差,方差,过拟合,欠拟合]

前言&#xff1a; 这章的目的主要是通过诊断错误的来源,通过错误的来源去优化,挑选模型。 通过本章掌握 过拟合(overfitting)和欠拟合(underfitting)出现原因及解决方案. 目录&#xff1a; 1 概述 2 方差,偏差现象 3 过拟合和欠拟合 4 模型选择 5 概率论回顾 一 概…

Linux:windows 和 Linux 之间文本格式转换

背景 在 Windows 上编辑的文件&#xff0c;放到 Linux 平台&#xff0c;有时会出现奇怪的问题&#xff0c;其中有一个是 ^M 引起的&#xff0c;例如这种错误&#xff1a; /bin/bash^M: bad interpreter 这个问题相信大家也碰到过&#xff0c;原因是 Windows 和 Linux 关于换行的…

【JS Promise, Promise.all 与 async/await用法详解】

目录 PromisePromise基本使用Promise可进行连续回调Promise回调可接受入参1.工作原理 async/await总结参考文档&#xff1a; 异步 let a 0setTimeout(() > {a 1}, 1000)console.log(a) // 0此时这个延迟就成为异步执行的了&#xff0c;a值还没有变1就被使用输出&#xff0…

linux下实现Qt程序实现开机自启动

1.原理 要想实现开机自启动&#xff0c;首先&#xff0c;QT是没有这种实现的&#xff0c;最好是靠电脑开机的启动目录启动软件&#xff0c;下面这个目录 /etc/xdg/autostart 这是操作系统中用于配置启动项的目录&#xff0c;该目录下存放着开机自启动的启动器(.desktop)文件…

Flink-时间流与水印

时间流与水印 一、背景二、时间语义1.事件时间&#xff08;event time&#xff09;2.读取时间&#xff08;ingestion time&#xff09;3.处理时间&#xff08;processing time&#xff09; 三、水印-Watermarks1.延迟和正确性2.延迟事件3.顺序流4.无序流5.并行流 四、Windows1.…

28 主题管理

1.如何删除主题 执行kafka-topics脚本&#xff0c;删除操作是异步的&#xff0c;执行完脚本只是把主题标记为已删除 2.删除主题失败 可能原因&#xff1a; 副本所在broker宕机了待删除主题的部分分区还在迁移 解决方法&#xff1a; 手动删除zk节点/admin/delete_topics下以…

初识Java 18-5 泛型

目录 动态类型安全 异常 混型 C中的混型 替代方案 与接口混合 使用装饰器模式 与动态代理混合 本笔记参考自&#xff1a; 《On Java 中文版》 动态类型安全 在Java 5引入泛型前&#xff0c;老版本的Java程序中就已经存在了List等原生集合类型。这意味着&#xff0c;我们…

【计算机网络笔记】交换机

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

【MySQL工具】my2sql-快速解析binlog

​​​​​​ 目录 ​​​​​​安装 my2sql简介 用途 工具优势 限制 账号所需权限 参数解析 场景 场景1 回滚 安装 安装比较简单 直接下载二进制命令即可使用 wget https://github.com/liuhr/my2sql/raw/master/releases/centOS_release_7.x/my2sql my2sql简介 …

AUTOSAR系统服务篇 - BswM

文章目录 模式仲裁仲裁规则模式条件和逻辑表达式模式仲裁的要求立即操作和延时操作初始化后的仲裁行为模式控制模式处理周期模式控制的要求触发和条件动作列表可用动作初始化后的模式控制行为等待功能多分区支持BswM接口和端口模式请求端口模式切换端口模式切换通知组件类型和内…

上海亚商投顾:沪指震荡下跌 成交量继续下破8000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整&#xff0c;深成指、创业板指午后跌超1%&#xff0c;北证50指数跌超7%&#xff0c;超百只北…

Windows11编译Hadoop3.3.6源码

由于https://github.com/kontext-tech/winutils还未发布3.3.6版本&#xff0c;因此尝试源码编译 目录 环境和安装包准备&#xff0c;见2zlib编译方法一&#xff1a;方法二&#xff1a; 配置文件更改1. maven阿里云镜像2. Node版本3. 越过Javadoc检查 编译HadoopError,其他报错…