用PHP +复述,事务怎么避免高并发引起的商品超卖问题

  介绍

这篇文章主要讲解了“用PHP +复述,事务怎么避免高并发引起的商品超卖问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用PHP +复述,事务怎么避免高并发引起的商品超卖问题”吧!

对于一些有一定用户量的电商网站,如果只是单纯的使用关系型数据库(如MySQL, Oracle)来做抢购,对数据库的压力是非常大的,而且如果不使用好数据库的锁机制,还会导致商品,优惠券超卖的问题。我所在的公司也遇到了同样的问题,问题发生在优惠券被超量抢购上,在问题发生后我们开始想办法解决问题,由于自己使用复述,比较多,我准备使用复述来解决这个问题。利用复述的高性能和事务特性来解决线上优惠券被超库存抢购的问题,下面我给出我临时解决这个问题的第一版的伪代码,去掉了一些细节:

/* *   ,*抢优惠券(秒杀)   ,* @param  int  couponId 美元;商品ID   ,* @param  int  uid 美元;用户ID   ,* @return 保龄球   ,*/function 秒杀(couponId美元,美元uid)   {//1。初始化复述,连接   ,redis 美元;=,new 复述();   ,if (! $复述→连接(& # 39;127.0.0.1 # 39;,,6379)),{   ,trigger_error(& # 39;复述,连接出的错! ! ! & # 39;,,E_USER_ERROR);   ,}else  {   ,echo  & # 39;连接正常& lt; br> & # 39;;   ,}      ,//秒杀商品的库存的关键   ,key 美元;=,& # 39;秒杀:& # 39;。美元couponId # 39;公司:股票# 39;;   美元,复述,→观察(关键);      ,//获取库存   ,stock 美元;=,复述,→美元(美元键);      ,//秒杀未开始,表示库存为null   ,if  (! $ stock ,,, ! is_numeric(股票)美元),{   ,echo  & # 39;秒杀未开始& # 39;;   ,return 假;   ,}      ,//判断库存,如果库存大于0,则减库存,将该成功秒杀用户加入哈希表,如果小于等于0,秒杀结束   ,if  (stock 美元;& lt;=, 0), {   ,echo  & # 39;秒杀已结束& # 39;;   ,return 假;   ,}      ,//用户已经成功秒杀过一次了,不允许再次参与秒杀   美元,if (复述→sIsMember(& # 39;秒杀:& # 39;。美元couponId # 39;公司:uid # 39;,,美元uid)), {   ,echo  & # 39;秒杀失败& # 39;;   ,return 假;   ,}      ,//代码走到这里,说明该用户是第一次参与秒杀,将库存减一,然后把这个人放到已抢到的集合表   ,//多(),返回一个复述对象,并进入多模模式,一旦进入多模模式,以后调用的所有方法都会返回相同的对象,   ,//直到exec()方法被调用。   美元,美元result =,复述,→多()→12月(键)→大块漂浮植物(& # 39;秒杀:& # 39;。美元couponId # 39;公司:uid # 39;,,美元uid)→exec ();      (空,if (结果)美元),{//事务被取消   ,echo  & # 39;秒杀失败& # 39;;   ,return 假;   ,}      ,//抢券成功,将优惠券ID和UID放入到队列中,由一个单独的进程队列来消费队列里的数据,向用户推送抢到的优惠券   美元,复述,→lPush (& # 39; couponOrder& # 39;,,美元couponId强生# 39;+ & # 39;美元uid);      美元,复述,→close ();   ,return 真实;   }      时间=美元couponId  11211;   $ uid =, mt_rand (1, 100);   secKill($couponId, $uid);

首先,我模拟设置优惠券ID为11211的优惠券库存为10个。

用PHP+Redis事务怎么避免高并发引起的商品超卖问题

然后,我们使用ab工具来模拟1000次请求,50并发量来测试

ab -n 1000 -c 50 www.test.com/

然后我们通过Redis Desktop Manager来查看一些Redis的结果

couponOrder队列里已经有了10个用户的信息了

用PHP+Redis事务怎么避免高并发引起的商品超卖问题

并且优惠券的剩余数量也是0了,不再是负数了

用PHP+Redis事务怎么避免高并发引起的商品超卖问题

同时,用户抢券集合里也保存了10个用户的UID信息。

用PHP+Redis事务怎么避免高并发引起的商品超卖问题

上面这串代码解决了两个问题: