用redis做一个简单的秒杀

下面是一个简单的下单操作

<?php
include "MMysql.class.php";
$configArr=[
	‘host‘=>,
	‘port‘=>,
	‘user‘=>,
	‘passwd‘=>,
	‘dbname‘=>,
];
$db = new MMysql($configArr);
$sql="select * from sdb_b2c_products where product_id=‘38‘";
$product=$db->doSql($sql);
if(!$product){
	echo "error:not find product";
	return;
}
$product=$product[0];
if($product[‘store‘]-$product[‘freez‘]<1){
	echo "error:no store";
	return;
}
$sql="select * from sdb_b2c_member_addrs where member_id=‘256187‘";
$addr=$db->doSql($sql);
$addr=$addr[0];
$data=[
	‘order_id‘=>date(‘ymdHis‘).rand(100,999),
	‘total_amount‘=>$product[‘price‘],
	‘final_amount‘=>$product[‘price‘],
	‘pay_status‘=>‘0‘,
	‘createtime‘=>time(),
	‘shipping_id‘=>‘13‘,
	‘shipping‘=>‘韵达‘,
	‘member_id‘=>‘636389‘,
	‘ship_area‘=>$addr[‘area‘],
	‘shipname‘=>$addr[‘name‘],
	‘ship_addr‘=>$addr[‘addr‘],
];
$order=$db->insert(‘sdb_b2c_orders‘,$data);
if($order){
	$sql="update sdb_b2c_products set freez=freez+1 where product_id=‘38‘";
	$db->doSql($sql);
	echo "order create success";
	return;
}else{
	echo "error:order create fail";
	return;
}

?>

代码解释为:

在商品表中找到商品,获取实际库存和虚拟库存,如果时间库存减去虚拟库存小于1,则表示没有库存了

如果有实际库存,则去找memeber_id为‘256187‘ 的会员收货地址信息,然后创建订单

如果订单创建成功,则更新虚拟库存。

用jmeter测试了在并发下的效果,设置500个线程去模拟并发

测试前设置实际库存store为50,虚拟库存freez为0,正常情况下freez只能达到50,否则就会有超卖的情况

实际测试,在高并发的情况下freez通常都大于50,在54左右。

由于获取库存是否还有,到更改库存中间有一定的时间差,所有高并发下会出现超卖的问题。

下面的代码经过修改,使用redis的list作为队列。

<?php
$store=50;
$redis=new Redis();
$result=$redis->connect(‘127.0.0.1‘,6379);
$res=$redis->llen(‘pro38‘);
echo $res;
$count=$store-$res;
for($i=0;$i<$count;$i++){
	$redis->lpush(‘pro38‘,1);
}
echo $redis->llen(‘pro38‘);
?>

上面是添加一个库存为50的redis的list

下面贴上下单代码

<?php
include "MMysql.class.php";
$configArr=[
	‘host‘=>‘121.41.38.44‘,
	‘port‘=>‘3306‘,
	‘user‘=>‘yuancheng‘,
	‘passwd‘=>‘yuancheng‘,
	‘dbname‘=>‘laiyifendb‘,
];
$db = new MMysql($configArr);
$redis=new Redis();
$result=$redis->connect(‘127.0.0.1‘,6379);

$count=$redis->lpop(‘pro38‘);
if(!$count){
	echo "error:no store redis";
	return;
}
$sql="select * from sdb_b2c_products where product_id=‘38‘";
$product=$db->doSql($sql);
if(!$product){
	echo "error:not find product";
	return;
}
$product=$product[0];
if($product[‘store‘]-$product[‘freez‘]<1){
	echo "error:no store";
	return;
}
$sql="select * from sdb_b2c_member_addrs where member_id=‘256187‘";
$addr=$db->doSql($sql);
$addr=$addr[0];
$data=[
	‘order_id‘=>date(‘ymdHis‘).rand(100,999),
	‘total_amount‘=>$product[‘price‘],
	‘final_amount‘=>$product[‘price‘],
	‘pay_status‘=>‘0‘,
	‘createtime‘=>time(),
	‘shipping_id‘=>‘13‘,
	‘shipping‘=>‘韵达‘,
	‘member_id‘=>‘636389‘,
	‘ship_area‘=>$addr[‘area‘],
	‘shipname‘=>$addr[‘name‘],
	‘ship_addr‘=>$addr[‘addr‘],
];
$order=$db->insert(‘sdb_b2c_orders‘,$data);
if($order){
	$sql="update sdb_b2c_products set freez=freez+1 where product_id=‘38‘";
	$db->doSql($sql);
	echo "order create success";
	return;
}else{
	echo "error:order create fail";
	return;
}

?>

经过测试,此方法可以防止超卖的发生

时间: 2024-10-10 15:37:06

用redis做一个简单的秒杀的相关文章

利用redis List队列简单实现秒杀 PHP代码实现

利用redis List队列简单实现秒杀 PHP代码实现 2018年05月28日 11:37:46 m_nanle_xiaobudiu 阅读数 35674更多 分类专栏: Redis 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m_nanle_xiaobudiu/article/details/80479666 一 生产者producer部分 ---------------------

使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Networking做一个简单的多人游戏例子-3/3 7. 在网络中控制Player移动 上一篇中,玩家操

[3] 用D3.js做一个简单的图表吧!

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为可缩放矢量图形(Scalable Vector Graphics),SVG 使用 XML 格式定义图像,不清楚什么是SVG的朋友请先在 w3cschools 学习下

用EF DataBase First做一个简单的MVC3报名页面

使用EF DataBase First做一个简单的MVC3报名网站 ORM(Object Relational Mapping)是面向对象语言中的一种数据访问技术,在ASP.NET中,可以通过ADO.NET Entity Framework技术来简化数据访问.在EF里,有Code First,Model First和DataBase First三种方法来实现. 百度百科关于ORM的介绍: http://baike.baidu.com/view/197951.htm?fr=aladdin 1.就像

【Python】 做一个简单的 http 服务器

# coding=utf-8 ''' Created on 2014年6月15日 @author: Yang ''' import socket import datetime # 初始化socket s = socket.socket() # 获取主机名, 也可以使用localhost # host = socket.gethostname() host = "localhost" # 默认的http协议端口号 port = 80 # 绑定服务器socket的ip和端口号 s.bin

Jmeter初步使用二--使用jmeter做一个简单的性能测试

经过上一次的初步使用,我们懂得了Jmeter的安装与初步使用的方法.现在,我们使用Jmeter做一个简单的性能测试.该次测试,提交的参数不做参数化处理,Jmeter各元件使用将在介绍在下一博文开始介绍并使用. 首先,打开Jmeter工具,并建立一个测试计划(测试脚本).启动jmeter后,jmeter会自动生成一个空的测试计划,我们可以基于该测试计划建立自己的测试计划. 步骤: 步骤一:添加线程组 一个性能测试请求负载是基于一个线程组完成的.一个测试计划必须有一个线程组.测试计划添加线程组非常简

使用React并做一个简单的to-do-list

1. 前言 说到React,我从一年之前就开始试着了解并且看了相关的入门教程,而且还买过一本<React:引领未来的用户界面开发框架 >拜读.React的轻量组件化的思想及其visual-dom的这种技术创新,也算是早就有了初步了解.一来没有学的太深入,二来后来在工作中和业余项目中都没有用到,因此慢慢的就更加生疏了. 近期,因为我想把自己的开源项目wangEditor能放在React.angular和vuejs中使用.先从react开始,顺手自己也重试一下React的基础知识,顺便再做一个小d

【 D3.js 入门系列 — 3 】 做一个简单的图表!

图1. 柱形图 1. 柱形图 前几章的例子,都是对文字进行处理.本章中将用 D3 做一个简单的柱形图.制作柱形图有很多种方法,比如用 HTML 的 <div> 标签,或在 SVG 上绘制 . SVG ,即可缩放矢量图形(Scalable Vector Graphics),使用 XML 格式定义图形,可在 W3School 学习 SVG 的相关语法,不需要记住所有标签,用的时候再查即可. 先看下面的代码: <script src="http://d3js.org/d3.v3.mi

【Bugly干货分享】一起用 HTML5 Canvas 做一个简单又骚气的粒子引擎

Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 前言 好吧,说是“粒子引擎”还是大言不惭而标题党了,离真正的粒子引擎还有点远.废话少说,先看[demo],扫描后点击屏幕有惊喜哦… 本文将教会你做一个简单的canvas粒子制造器(下称引擎). 世界观 这个简单的引擎里需要有三种元素:世界(World).发射器(Launcher).粒子(Grain).总得来说就是:发射器存在于世界之中,