php结合redis实现秒杀功能
<?php
$conn
=mysql_connect(
"localhost"
,
"big"
,
"123456"
);
if
(!
$conn
){
echo
"connect failed"
;
exit
;
}
mysql_select_db(
"big"
,
$conn
);
mysql_query(
"set names utf8"
);
$price
=10;
$user_id
=1;
$goods_id
=1;
$sku_id
=11;
$number
=1;
//生成唯一订单
function
build_order_no(){
return
date
(
'ymd'
).
substr
(implode(NULL,
array_map
(
'ord'
,
str_split
(
substr
(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function
insertLog(
$event
,
$type
=0){
global
$conn
;
$sql
="insert into ih_log(event,type)
values(
'$event'
,
'$type'
)";
mysql_query(
$sql
,
$conn
);
}
//模拟下单操作
//库存是否大于0
$sql
=
"select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'"
;
//解锁 此时ih_store数据中goods_id='$goods_id' and sku_id='$sku_id' 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行
$rs
=mysql_query(
$sql
,
$conn
);
$row
=mysql_fetch_assoc(
$rs
);
if
(
$row
[
'number'
]>0){
//高并发下会导致超卖
$order_sn
=build_order_no();
//生成订单
$sql
="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
values(
'$order_sn'
,
'$user_id'
,
'$goods_id'
,
'$sku_id'
,
'$price'
)";
$order_rs
=mysql_query(
$sql
,
$conn
);
//库存减少
$sql
=
"update ih_store set number=number-{$number} where sku_id='$sku_id'"
;
$store_rs
=mysql_query(
$sql
,
$conn
);
if
(mysql_affected_rows()){
insertLog(
'库存减少成功'
);
}
else
{
insertLog(
'库存减少失败'
);
}
}
else
{
insertLog(
'库存不够'
);
}
?>.
<?php
$conn
=mysql_connect(
"localhost"
,
"big"
,
"123456"
);
if
(!
$conn
){
echo
"connect failed"
;
exit
;
}
mysql_select_db(
"big"
,
$conn
);
mysql_query(
"set names utf8"
);
$price
=10;
$user_id
=1;
$goods_id
=1;
$sku_id
=11;
$number
=1;
//生成唯一订单号
function
build_order_no(){
return
date
(
'ymd'
).
substr
(implode(NULL,
array_map
(
'ord'
,
str_split
(
substr
(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function
insertLog(
$event
,
$type
=0){
global
$conn
;
$sql
="insert into ih_log(event,type)
values(
'$event'
,
'$type'
)";
mysql_query(
$sql
,
$conn
);
}
//模拟下单操作
//库存是否大于0
mysql_query(
"BEGIN"
);
//开始事务
$sql
=
"select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' FOR UPDATE"
;
//此时这条记录被锁住,其它事务必须等待此次事务提交后才能执行
$rs
=mysql_query(
$sql
,
$conn
);
$row
=mysql_fetch_assoc(
$rs
);
if
(
$row
[
'number'
]>0){
//生成订单
$order_sn
=build_order_no();
$sql
="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
values(
'$order_sn'
,
'$user_id'
,
'$goods_id'
,
'$sku_id'
,
'$price'
)";
$order_rs
=mysql_query(
$sql
,
$conn
);
//库存减少
$sql
=
"update ih_store set number=number-{$number} where sku_id='$sku_id'"
;
$store_rs
=mysql_query(
$sql
,
$conn
);
if
(mysql_affected_rows()){
insertLog(
'库存减少成功'
);
mysql_query(
"COMMIT"
);
//事务提交即解锁
}
else
{
insertLog(
'库存减少失败'
);
}
}
else
{
insertLog(
'库存不够'
);
mysql_query(
"ROLLBACK"
);
}
?>
<?php
$conn=mysql_connect("localhost","root","123456");
if(!$conn){
echo "connect failed";
exit;
}
mysql_select_db("big-bak",$conn);
mysql_query("set names utf8");
$price=10;
$user_id=1;
$goods_id=1;
$sku_id=11;
$number=1;
//生成唯一订单号
function build_order_no(){
return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function insertLog($event,$type=0){
global $conn;
$sql="insert into ih_log(event,type)
values('$event','$type')";
mysql_query($sql,$conn);
}
$fp = fopen("lock.txt", "w+");
if(!flock($fp,LOCK_EX | LOCK_NB)){
echo "系统繁忙,请稍后再试";
return;
}
//下单
$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";
$rs=mysql_query($sql,$conn);
$row=mysql_fetch_assoc($rs);
if($row['number']>0){//库存是否大于0
//模拟下单操作
$order_sn=build_order_no();
$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
values('$order_sn','$user_id','$goods_id','$sku_id','$price')";
$order_rs=mysql_query($sql,$conn);
//库存减少
$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
$store_rs=mysql_query($sql,$conn);
if(mysql_affected_rows()){
insertLog('库存减少成功');
flock($fp,LOCK_UN);//释放锁
}else{
insertLog('库存减少失败');
}
}else{
insertLog('库存不够');
}
fclose($fp);
第四种,使用redis队列
<?php
$store
=1000;
$redis
=
new
Redis();
$result
=
$redis
->connect(
'127.0.0.1'
,6379);
$res
=
$redis
->llen(
'goods_store'
);
echo
$res
;
$count
=
$store
-
$res
;
for
(
$i
=0;
$i
<
$count
;
$i
++){
$redis
->lpush(
'goods_store'
,1);
}
echo
$redis
->llen(
'goods_store'
);
?>
php结合redis实现秒杀功能的更多相关文章
- thinkphp+redis实现秒杀功能
好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbi ...
- thinkphp+redis实现秒杀功能(转)
1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...
- 电商项目中使用Redis实现秒杀功能
参与过抢购活动就知道,很明显的一点是商即便商品实际没有了也是可以下单成功的,但是在支付的时候会提示你商品没有了. 实现原理:list双向链表 使用redis队列,因为pop操作是原子的,即使有很多用户 ...
- php+redis实现电商秒杀功能
这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...
- Redis事务和实现秒杀功能的实现
今天带着学生学习了Redis的事务功能,Redis的事务与传统的关系型数据库(如MySQL)有所不同,Redis的事务不能回滚. Redis中使用multi.exec.discard.watch.un ...
- Redis分布式锁实现简单秒杀功能
这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...
- thinkphp+redis实现秒杀,缓存等功能
秒杀是商城常见功能 php+redis是最常见的秒杀功能 1,安装redis,根据自己的php版本安装对应的redis扩展 首先查看phpinfo();php环境信息 2,下载redis https ...
- spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)
一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...
- 秒杀功能压测 jmeter--------重要!!!
线程组里面有三个接口请求,依次为:显示商品列表.登录秒杀平台账户.进行秒杀 对线程组用5000个线程循环10次 设置一下默认配置,之后就不用反复填写了 设置配置文件这个具体功能就是读text文件并且设 ...
随机推荐
- Windows环境下多线程编程原理与应用读书笔记(3)————Windows环境中的多线程实现(3)
纤程 纤程(fiber): 相当于用户级别的线程或轻进程.纤程由Win32库函数支持,对核心是不可见的.纤程可以通过SwitchToFiber显示至另一合作纤程,以实现合作纤程之间的协同.线程是在Wi ...
- JavaScript基础一(js基础函数与运算符)
[使用js的三种方式] 1.在HTML标签中,直接内嵌js(并不提倡使用) <button onclick=" alert('点就点')"> 点我啊</butto ...
- linux 安装 Elasticsearch5.6.x 详细步骤以及问题解决方案
在网上有很多那种ES步骤和问题的解决 方案的,不过没有一个详细的整合,和问题的梳理:我就想着闲暇之余,来记录一下自己安装的过程以及碰到的问题和心得:有什么不对的和问题希望及时拍砖. 第一步:环境 li ...
- python3 多线程获取数据实例
import requestsimport jsonfrom retrying import retryfrom lxml import etreefrom queue import Queueimp ...
- MySQLbase
/*多行注释*/-- 单行注释-- 创建用户: CREATE USER '用户名'[@'主机名'] IDENTIFIED BY '密码'-- 主机名可以为空,省略主机名表示默认权限为%, 所有主机都可 ...
- Duilib XML嵌套
duilib使用嵌套xml可以简化代码的书写,有利于模块化的页面布局分解,duilib库的xml嵌套主要有两种方式 方式一.以创建控件的方式嵌套xml 在CreateControl(LPCTSTR p ...
- Unity3D高性能战争迷雾实现
效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的. 战争 ...
- csv格式订单下载,完成后伴随邮件通知下载
前言 功能开发中会遇到大量订单下载,而服务器的请求响应时间又配置的很短,导致下载时候请求超时. 这篇文章主要思路:异步查询数据,生成csv文件,放入email中并发送给用户.(异步部分本文不做介绍,配 ...
- MyRapid WinForm 快速开发框架
MyRapid 框架介绍开发历程:作者是数据库相关软件开发从业人员,懒惰的,能交给电脑做的事情懒得自己做开发目的:处理底层数据传输,减少工作量,提高开发效率框架特点:数据库相关开发.易学易用.快速上手 ...
- PL/SQL 游标 (实验七)
PL/SQL 游标 emp.dept 目标表结构及数据 要求 基于部门表建立游标dept_cursor1,使用记录变量接收游标数据,输出部门表信息: 显示格式: 部 门 号: XXX 部门名称: XX ...