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文件并且设 ...
随机推荐
- awake()和start()还有update(),fixedupdate()的差别
1.首先看一下untiy官方对awake()和start()的定义 awake()和start()函数会在脚本加载后自动调用,awake()会先被调用,即使脚本未被调用.最好用来设置脚本之间的引用和初 ...
- 一个有意思的Python小程序(全国省会名称随机出题)
本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 最近比较迷Python,仿照<Python编程快速上手>8.5写了一个随机出卷的小 ...
- 深度学习系列 Part (2)
1. 神经网络原理 神经网络模型,是上一章节提到的典型的监督学习问题,即我们有一组输入以及对应的目标输出,求最优模型.通过最优模型,当我们有新的输入时,可以得到一个近似真实的预测输出. 我们先看一下如 ...
- TCP协议的滑动窗口协议以及流量控制
参考资料 http://blog.chinaunix.net/uid-26275986-id-4109679.html http://network.51cto.com/art/201501/4640 ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) K Tournament Wins
题目链接:http://codeforces.com/gym/101201 /* * @Author: lyucheng * @Date: 2017-10-22 14:38:52 * @Last Mo ...
- 小明滚出---响应对象HttpServletResponse和请求对象HttpServletRequest实例
<Servlet类的Java> @WebServlet("/studentServlet") public class StudentServlet extends H ...
- asp.net 自定义的模板方法接口通用类型
本来想写这个帖子已经很久了,但是公司事情多,做着做着就忘记了.公司因为需要做接口,而且用的还是asp.net的老框架,使用Handler来做,没得办法,自己照着MVC写了一个通过的接口操作模板. 上送 ...
- mac下selenium+python环境搭建
selenium2+python的环境搭建主要需要python和selenium 1.python mac下自带了python,可以查看版本.当然可以选择安装其它版本的python. 2.seleni ...
- Java面试宝典
相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消 ...
- 非对称加密技术- RSA算法数学原理分析
非对称加密技术,在现在网络中,有非常广泛应用.加密技术更是数字货币的基础. 所谓非对称,就是指该算法需要一对密钥,使用其中一个(公钥)加密,则需要用另一个(私钥)才能解密. 但是对于其原理大部分同学应 ...