对于高并发下的场景,一般都是采用redis缓存机制来处理。

当然也不是只有redis可以处理、还有利用mysql事务操作锁住操作的行、文件锁。

不过这些方式都没有redis缓存高效、可靠。

模拟的过程:

首先将商品库存,存储到redis当中。

使用redis队列、来实现相应的操作。

<?php
$store = 500;//模拟库存
$redis = new Redis();
$result = $redis->connect('127.0.0.1',6379);
$res = $redis->llen('goods_store');
echo $res."<br/>";
$count = $store - $res;
for($i=0;$i<$count;$i++){
$redis->lpush('goods_store',1);//入队列一个商品
}
echo $redis->llen('goods_store');
?>

下单过程:

<?php
header("Content-Type:text/html;charset=utf-8"); $conn = mysql_connect("192.168.139.136","root","1234");
if(!$conn){
echo "数据库连接失败";exit();
}
mysql_select_db("shop",$conn);
mysql_query("set names utf8"); //生成唯一订单号
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 `shop_log`(`event`,`type`) VALUES('{$event}',{$type})";
//echo $sql;
mysql_query($sql,$conn);
} //模拟场景
$price = 10;
$user_id = 1;
$goods_id = 1;
$sku_id = 11;
$number = 1; //模拟下单操作
//下单时判断redis队列库存量
$redis = new Redis();
$result = $redis->connect("127.0.0.1",6379);
$count = $redis->lpop("goods_store");//下单一次、队列中弹出一个商品
if(!$count){
insertLog("redis中没有库存");
return;
} $order_sn=build_order_no();
//生成订单
$sql="INSERT INTO `shop_order`(`order_sn`,`user_id`,`goods_id`,`sku_id`,`price`) VALUES({$order_sn},{$user_id},{$goods_id},{$sku_id},{$price})";
$order_res=mysql_query($sql,$conn); //库存减少
$sql="UPDATE `shop_store` SET `number` = number - {$number} WHERE `sku_id` = {$sku_id}";
$store_res=mysql_query($sql,$conn);
if(mysql_affected_rows()){
insertLog('库存减少成功');
}else{
insertLog('库存减少失败');
}
?>

模拟的数据表:

/*
Navicat MySQL Data Transfer Source Server : centos(1)
Source Server Version : 50552
Source Host : 192.168.139.136:3306
Source Database : shop Target Server Type : MYSQL
Target Server Version : 50552
File Encoding : 65001 Date: 2017-05-03 10:08:23
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for shop_goods
-- ----------------------------
DROP TABLE IF EXISTS `shop_goods`;
CREATE TABLE `shop_goods` (
`goods_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`cat_id` int(11) NOT NULL COMMENT '商品分类ID',
`goods_name` varchar(255) NOT NULL COMMENT '商品名称',
PRIMARY KEY (`goods_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='@商品表'; -- ----------------------------
-- Records of shop_goods
-- ----------------------------
INSERT INTO `shop_goods` VALUES ('1', '0', '小米手机'); -- ----------------------------
-- Table structure for shop_log
-- ----------------------------
DROP TABLE IF EXISTS `shop_log`;
CREATE TABLE `shop_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event` varchar(255) NOT NULL,
`type` tinyint(4) NOT NULL DEFAULT '0',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=91602 DEFAULT CHARSET=utf8 COMMENT='@日志表'; -- ----------------------------
-- Records of shop_log
-- ---------------------------- -- ----------------------------
-- Table structure for shop_order
-- ----------------------------
DROP TABLE IF EXISTS `shop_order`;
CREATE TABLE `shop_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_sn` char(32) NOT NULL,
`user_id` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`goods_id` int(11) NOT NULL DEFAULT '0',
`sku_id` int(11) NOT NULL DEFAULT '0',
`price` float NOT NULL,
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2022 DEFAULT CHARSET=utf8 COMMENT='@订单表'; -- ----------------------------
-- Records of shop_order
-- ---------------------------- -- ----------------------------
-- Table structure for shop_store
-- ----------------------------
DROP TABLE IF EXISTS `shop_store`;
CREATE TABLE `shop_store` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL,
`sku_id` int(10) unsigned NOT NULL DEFAULT '0',
`number` int(10) unsigned NOT NULL DEFAULT '0',
`freez` int(11) NOT NULL DEFAULT '0' COMMENT '虚拟库存',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='@库存'; -- ----------------------------
-- Records of shop_store
-- ----------------------------
INSERT INTO `shop_store` VALUES ('1', '1', '11', '0', '0');

  

php+redis实现高并发模拟下单、秒杀、抢购操作的更多相关文章

  1. php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  2. php结合redis实现高并发下的抢购、秒杀功能 (转载)

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...

  3. php 结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  4. php结合redis实现高并发下的抢购、秒杀功能【转】

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  5. php结合redis实现高并发下的抢购、秒杀功能 (转)

      抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易 ...

  6. (高级篇)php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  7. redis实现高并发下的抢购/秒杀功能

    之前写过一篇文章,高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢 ...

  8. 【转】php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  9. Redis实现高并发下的抢购、秒杀功能

    博主最近在项目中遇到了抢购问题!现在分享下.抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖" ...

随机推荐

  1. 【BZOJ3864】Hero meet devil DP套DP

    [BZOJ3864]Hero meet devil Description There is an old country and the king fell in love with a devil ...

  2. springcloud微服务实战--笔记--1、基础知识

    微服务的问题: 分布式事务和数据一致性. 由于分布式事务本身第实现难度就非常大,所以在微服务架构中,我们更强调在各服务之间进行无事务第调用,而对于数据一致性,只要求数据在最后第处理状态是一致第即可:若 ...

  3. Eclipse如何删除插件

    删除Eclipse安装的插件方法: help -> install new softWare -> what is already installed ->选中 要卸载的插件 -&g ...

  4. css多余字符显示省略号

    width:300px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; ;

  5. 性能测试--Jmeter之wordpress示例

    Jmeter之wordpress示例 WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理 ...

  6. 用keytool创建Keystore和Trustsotre文件只需五步

    用keytool创建Keystore和Trustsotre文件 JSSE使用Truststore和Keystore文件来提供客户端和服务器之间的安全数据传输.keytool是一个工具可以用来创建包含公 ...

  7. 7-4 汉密尔顿回路(25 分) 【STL】

    7-4 汉密尔顿回路(25 分) 著名的"汉密尔顿(Hamilton)回路问题"是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次).本题就要求你判断任一给定的回路是 ...

  8. WIFI模块ESP8266的使用指南【转】

    本文转载自:http://www.itdadao.com/articles/c15a814052p0.html 本文主要对讲述ESP8266模块硬件连接工作,以及作为服务器和客户端情况下的配置实现的详 ...

  9. 51nod 1533 && CF538F

    题目:难以简述,请传送门 神犇题解Ⅰ   神犇题解Ⅱ 好劲啊跪在地上..完全没接触过K叉树的性质.. 对于每个询问,我们并不关心叶节点,只关心其他的节点.而一个完整K叉树的内节点个数是O(n/k)的, ...

  10. nginx应用 突破高并发的性能优化

    摘自:http://www.cnblogs.com/kevingrace/p/6094007.html 在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题. ...