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 开始 PHP 会话
Dec 21 PHP
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
May 24 PHP
php对csv文件的读取,写入,输出下载操作详解
Aug 10 PHP
php遍历目录与文件夹的多种方法详解
Nov 14 PHP
php使用GD实现颜色渐变实例
Jun 02 PHP
详解PHP数组赋值方法
Nov 07 PHP
Linux安装配置php环境的方法
Jan 14 PHP
Yii2中Restful API原理实例分析
Jul 25 PHP
利用php实现一周之内自动登录存储机制(cookie、session、localStorage)
Oct 31 PHP
Yii2第三方类库插件Imagine的安装和使用
Jul 06 PHP
使用vs code编辑调试php配置的方法
Jan 29 PHP
PHP防止sql注入小技巧之sql预处理原理与实现方法分析
Dec 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蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
php中引用符号(&)的使用详解
2013/11/13 PHP
PHP学习笔记(二) 了解PHP的基本语法以及目录结构
2014/08/04 PHP
PHP技术开发微信公众平台
2015/07/22 PHP
php实现简单加入购物车功能
2017/03/07 PHP
在PHP中实现使用Guzzle执行POST和GET请求
2019/10/15 PHP
基于jquery的3d效果实现代码
2011/03/23 Javascript
jQuery源码分析-01总体架构分析
2011/11/14 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
2013/01/15 Javascript
ajaxFileUpload.js插件支持多文件上传的方法
2014/09/02 Javascript
javascript实现英文首字母大写
2015/04/23 Javascript
简介JavaScript中toUpperCase()方法的使用
2015/06/06 Javascript
分享一个插件实现水珠自动下落效果
2016/06/01 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
2016/06/26 Javascript
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
使用DataTable插件实现异步加载数据
2017/11/19 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
vue3.0 自适应不同分辨率电脑的操作
2021/02/06 Vue.js
[01:55]《走出家门看比赛》——DOTA2 2015国际邀请赛同城线下观战
2015/07/18 DOTA
Python中的闭包总结
2014/09/18 Python
通过Python实现自动填写调查问卷
2017/09/06 Python
python输出100以内的质数与合数实例代码
2018/07/08 Python
python读取图片并修改格式与大小的方法
2018/07/24 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
Python3中lambda表达式与函数式编程讲解
2019/01/14 Python
Django uwsgi Nginx 的生产环境部署详解
2019/02/02 Python
美国网上订购鲜花:FTD
2016/09/23 全球购物
FORZIERI澳大利亚站:全球顶级奢华配饰精品店
2016/12/31 全球购物
机械设计专业大学生职业生涯规划书范文
2014/09/13 职场文书
党的群众路线教育实践活动对照检查材料(教师)
2014/09/24 职场文书
学生评语集锦
2015/01/04 职场文书
团员个人年度总结
2015/02/26 职场文书
教你如何用python开发一款数字推盘小游戏
2021/04/14 Python
Linux中一对多配置日志服务器的详细步骤
2022/07/23 Servers