如何用php新增税金一列_商品超卖问题,你用PHP如何解决?

3661e54e9caed0accc554147e3e89d60.gif

文章来自:php自学中心网站
链接:http://www.startphp.cn/front/php/122784.html
作者:磊丰

商务合作:请加微信(QQ):2230304070

90432e9dd95cfcad62514f359dde9d45.png

视频教程

0b136fbca0ed1b868f67d261f6c80410.png

码农网每天更新3个教程:http://www.mano100.cn    158RMB升级永久会员,即可查看网站全部视频教程。有问题请咨询微信:2230304070    2d8102e8f9c0beb1d464e19499722162.png2d8102e8f9c0beb1d464e19499722162.png2d8102e8f9c0beb1d464e19499722162.png

ea56c63eea825ed0a3e72e199cb8c0bf.gif

90432e9dd95cfcad62514f359dde9d45.png

文章正文

0b136fbca0ed1b868f67d261f6c80410.png

商场活动秒杀超卖问题,实际上是商品抢购活动,如果一个商品中有100件库存,但是在抢购过程中有1000人来抢购,那么就会出现并发情况, 最初只有100个库存,但要抢购,人数过多,数据库中将只有100个库存,但是当库存为0时也是有人会成功提交。这是超卖问题。

这篇文章是简单的用redis队列来解决超卖问题。redis有list类型,而list类型一个双向链表。我们可以通过push和pop操作从链表的头部或者尾部添加或者删除元素。这么一来list既可以用作栈,也可以用作队列。这里就不对队列做更多的解释。这用redis就解决了并发的问题,在队列里先进先出,有效的解决超卖的问题。

如何设计表?

这里新建三张表: store商品表    

CREATE TABLE `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) NOT NULL DEFAULT '0',
  `freez` float(11,2) NOT NULL DEFAULT '0.00' COMMENT '虚拟库存',
  `price` int(10) NOT NULL COMMENT '价格:单位为分',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='库存表';

order订单表

CREATE TABLE `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',
  `number` int(11) NOT NULL,
  `price` int(10) NOT NULL COMMENT '价格:单位为分',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='订单表';

log日志表

CREATE TABLE `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=1 DEFAULT CHARSET=utf8;

如何实现呢?

首先将库存循环lpush进入redis值,比如goods_number里去,然后在下单的时候按照次序rpop出来。这样就是下一个单,然后取出来,依次进入队列,等goods_number的值为0时,终止下单。

好了,接下来,我们来看看代码是如何实现的

<?php namespace Home\Controller;use Think\Cache\Driver\Redis;use Think\Controller;class TestController extends Controller {public function index(){
        $wheres = array();
        $wheres['goods_id'] = 1;
        $number = Store::where($wheres)->get(['number']);
        $redis = new Redis(); for($i=0;$i         $redis->lpush('goods_number',1);  
    }  echo $redis->llen('goods_number');  
    }//生成唯一订单号  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){
        $data['event'] = $event;
        $data['type']  = $type;
        $res = M('log')->add($data);
    }  //模拟下单操作  //下单前判断redis队列库存量  function order(){
        $sku_id  = 11;  //假如传入已知的sku_id;
        $wheres = array();
        $wheres['sku_id'] = $sku_id;
        $good_info = Store::where($wheres)->find();
        $user_id  = rand(1,200);
        $goods_id = $good_info['goods_id'];
        $price    = $good_info['price'];
        $number   = 1;//抢购时每次买一件商品
        $redis=new Redis();
        $count=$redis->rpop('goods_number');  //下单时做rpop 从goods_number中取出1if($count == 0){  $this->insertLog('error:no goods_number redis');  return;  
        }if( ($good_info['number'] - $number) <= 0){$this->insertLog('商品售罄');  //如果库存为0写入日志 并停止下单操作return;
        }//生成订单    
        $order_sn=$this->build_order_no();
        $data = [];
        $data['order_sn'] = $order_sn;
        $data['user_id']  = $user_id;
        $data['goods_id'] = $goods_id;
        $data['sku_id']   = $sku_id;
        $data['number']   = $number;
        $data['price']    = $price;
        $order_rs=Order::create($data);//库存减少  
        $wheres['sku_id'] = $sku_id;
        $store_rs=Store::where($wheres)->setDec('number',$number);if($store_rs){$this->insertLog('库存减少成功');  
        }else{    $this->insertLog('库存减少失败');  
        }
    }
}

1、将库存循环存入good_number中   调用index方法

356cc9a096d46bd1cdacd21d415b18e1.png

2.然后进行并发下单操作。这里用Apache 的ab测试

运行: 

在Windows系统下,打开cmd命令行窗口,定位到apache安装目录的bin目录下 E:\phpStudy\bin\apache\apache2.4.9\bin

键入命令: 

ab -n 800 -c 800   http://www.startphp.cn/test/order

(-n发出800个请求,-c模拟800并发,请求数要大于或等于并发数。相当800人同时访问,后面是测试url )

a714f3d745a3da10b0d1e1c2c6e82266.png

执行成功 查看表数据

e0a903cb9b0d2352b5d402962de8abbb.png

b6d5e8e183b88a13e8d27acb0377b427.png

1d025e48c33ccde87c7a896e5dc3fe51.png

从表里我们可以看得出来,库存减少到0时,订单也就100个,而log表里也会清晰的记录着。

以上是本文的全部内容,希望对大家的学习有帮助,也希望大家多多支持 php自学中心 感谢阅读!

d20ba3b0940a5a3b2c837dd52c415df2.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值