码迷,mamicode.com
首页 > 数据库 > 详细

使用Mysql和Redis设计抢购逻辑

时间:2018-02-01 18:26:50      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:ble   record   charset   err   while   mys   时间   开始时间   div   

抢购场景中,要保证两点:

1.库存不会超减/少卖

2.在1基础上的执行速度

我测试了两种方案,

方案一.Mysql开启事务

我把库存表简单设计如下

CREATE TABLE `la_store` (
  `id` int(11) NOT NULL,
  `val` int(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

假设库存有100000件(val=100000)

php逻辑代码

<?php
$stime=microtime(true);
$count=100000;//测试次数
while($count>0){
$count-=1;
$con = mysql_connect("localhost","user","pwd");
if (!$con)
  {
  die(‘Could not connect: ‘ . mysql_error());
  }
mysql_select_db("database_name", $con);
mysql_query(‘begin‘);
$record=mysql_query("select * from la_store where id = 1 for update");//获取独占锁
$record=mysql_fetch_array($record);
if($record[‘val‘]>0){//判断是否还有库存
//有库存的逻辑
$res=mysql_query("UPDATE la_test SET val = val-1 WHERE id=1 ");//更新库存
}else{
//没库存的逻辑
}
mysql_query("commit"); mysql_close($con); } $etime=microtime(true);//获取程序执行结束的时间 $total=$etime-$stime; echo $total;

方案二.使用Redis开启事务

假设库存有100000件(set store 100000)

<?php
$stime=microtime(true);//开始时间
$count=100000;//测试次数
while($count>0){
$count-=1;
$redis = new Redis();
   $redis->connect(‘127.0.0.1‘, 6379);
$res=$redis->multi()->decr(‘store‘)->get(‘store‘)->exec();
if($res[1]>0){
        //有库存逻辑
}else{
        //没有库存逻辑
}
}
$etime=microtime(true);//获取程序执行结束的时间
print_r($res);
$total=$etime-$stime;
echo $total;

测试结果:

分别执行,经过100000次循环后,Redis用时22秒,Mysql用时50秒;

使用Redis更快,但Redis的事务不能回滚,如果业务逻辑出错时允许不回滚,并且回滚的概率很小,建议使用Redis.如果逻辑出错时必须回滚,还是用Mysql更稳妥.

使用Mysql和Redis设计抢购逻辑

标签:ble   record   charset   err   while   mys   时间   开始时间   div   

原文地址:https://www.cnblogs.com/ch459742906/p/8400412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!