PHP利用Mysql锁解决高并发的方法


Posted in PHP onSeptember 04, 2018

前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用Mysql的锁来解决高并发的问题

先看没有利用事务的时候并发的后果

创建库存管理表

CREATE TABLE `storage` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `number` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

创建订单管理表

CREATE TABLE `order` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `number` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=latin1

测试代码

$pdo = new PDO('mysql:host=127.0.0.1;port=3306; dbname=test','root','123456');
$sql="select `number` from storage where id=1 limit 1";
$res = $pdo->query($sql)->fetch();
$number = $res['number'];

if($number>0)
{
  $sql ="insert into `order` VALUES (null,$number)";
  
  $order_id = $pdo->query($sql);
  if($order_id)
  {

    $sql="update storage set `number`=`number`-1 WHERE id=1";
    $pdo->query($sql);
  }
}

我们预置库存是十个,然后执行ab测试查看结果

mysql> select * from storage
  -> ;
+----+--------+
| id | number |
+----+--------+
| 1 |   -2 |
+----+--------+
1 row in set (0.00 sec)

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 22 |   10 |
| 23 |   10 |
| 24 |   8 |
| 25 |   8 |
| 26 |   7 |
| 27 |   6 |
| 28 |   4 |
| 29 |   3 |
| 30 |   2 |
| 31 |   2 |
| 32 |   2 |
| 33 |   1 |
+----+--------+
12 rows in set (0.00 sec)

得到了订单共有12个,而库存表的库存也减到了-2,这显然不符合实际逻辑的;

下面我们来看利用数据库行锁来解决这个问题

修改代码如下

$pdo = new PDO('mysql:host=127.0.0.1;port=3306; dbname=test','root','123456');
$pdo->beginTransaction();//开启事务
$sql="select `number` from storage where id=1 for UPDATE ";//利用for update 开启行锁
$res = $pdo->query($sql)->fetch();
$number = $res['number'];

if($number>0)
{
  $sql ="insert into `order` VALUES (null,$number)";

  $order_id = $pdo->query($sql);
  if($order_id)
  {

    $sql="update storage set `number`=`number`-1 WHERE id=1";
    if($pdo->query($sql))
    {
      $pdo->commit();//提交事务
    }
    else
    {
      $pdo->rollBack();//回滚
    }

  }
  else
  {
    $pdo->rollBack();//回滚
  }
}

查看结果

mysql> select * from storage;
+----+--------+
| id | number |
+----+--------+
| 1 |   0 |
+----+------
--+
1 row in set (0.00 sec)

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 1 |   10 |
| 2 |   9 |
| 3 |   8 |
| 4 |   7 |
| 5 |   6 |
| 6 |   5 |
| 7 |   4 |
| 8 |   3 |
| 9 |   2 |
| 10 |   1 |
+----+--------+
10 rows in set (0.00 sec)

很明显在利用了mysql锁之后,对库存进行了有效的控制,很好的解决了第一段代码里面,因为并发引起的一些逻辑性的问题

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
新安装的MySQL数据库需要注意的安全知识
Jul 30 PHP
PHP采集利器 Snoopy 试用心得
Jul 03 PHP
使用PHPMyAdmin修复论坛数据库的图文方法
Jan 09 PHP
yii实现CheckBox复选框在同一行显示的方法
Dec 03 PHP
php图像处理类实例
Jul 28 PHP
PHP表单验证内容是否为空的实现代码
Nov 14 PHP
php使用gd2绘制基本图形示例(直线、圆、正方形)
Feb 15 PHP
ThinkPHP开发--使用七牛云储存
Sep 14 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
Sep 30 PHP
PHP实现打包下载文件的方法示例
Oct 07 PHP
PHP ADODB实现分页功能简单示例
May 25 PHP
thinkphp5.1 文件引入路径问题及注意事项
Jun 13 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
Sep 03 #PHP
PHP实现的AES双向加密解密功能示例【128位】
Sep 03 #PHP
PHP实现的日历功能示例
Sep 01 #PHP
thinkPHP5框架分页样式类完整示例
Sep 01 #PHP
php操作mongodb封装类与用法实例
Sep 01 #PHP
thinkphp集成前端脚手架Vue-cli的教程图解
Aug 30 #PHP
Django中通过定时任务触发页面静态化的处理方式
Aug 29 #PHP
You might like
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
PHP微信刮刮卡 附微信接口
2016/07/22 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
科讯商业版中用到的ajax空间与分页函数
2007/09/02 Javascript
javascript iframe内的函数调用实现方法
2009/07/19 Javascript
ext checkboxgroup 回填数据解决
2009/08/21 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
js使用递归解析xml
2014/12/12 Javascript
jQuery页面元素动态添加后绑定事件丢失方法,非 live
2016/06/16 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
如何使用Bootstrap 按钮实例详解
2017/03/29 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
jQuery利用FormData上传文件实现批量上传
2018/12/04 jQuery
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
2020/06/03 Javascript
如何使用原生Js实现随机点名详解
2021/01/06 Javascript
JavaScript canvas实现跟随鼠标移动小球
2021/02/09 Javascript
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
Python Web开发模板引擎优缺点总结
2014/05/06 Python
Python注释详解
2016/06/01 Python
Django中cookie的基本使用方法示例
2018/02/03 Python
python kmeans聚类简单介绍和实现代码
2018/02/23 Python
Python实现查找最小的k个数示例【两种解法】
2019/01/08 Python
Python为何不能用可变对象作为默认参数的值
2019/07/01 Python
Python函数的迭代器与生成器的示例代码
2020/06/18 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
带有css3动画效果的兼容多浏览器简单导航条示例
2014/01/26 HTML / CSS
CSS实现限制字数功能当对象内文本溢出时显示省略标记
2014/08/20 HTML / CSS
联想英国官网:Lenovo英国
2019/07/17 全球购物
Yahoo的PHP面试题
2014/05/26 面试题
演讲比赛策划方案
2014/06/11 职场文书
承诺书范本
2015/01/21 职场文书
2015年女生节活动总结
2015/02/27 职场文书
员工旷工检讨书
2015/08/15 职场文书
《辉夜大小姐想让我告白》第三季正式预告
2022/03/20 日漫
MongoDB支持的数据类型
2022/04/11 MongoDB