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 相关文章推荐
利用PHP+JS实现搜索自动提示(实例)
Jun 09 PHP
PHP图片上传代码
Nov 04 PHP
PHP整数取余返回负数的相关解决方法
May 15 PHP
php目录遍历函数opendir用法实例
Nov 20 PHP
浅析iis7.5安装配置php环境
May 10 PHP
解读PHP中上传文件的处理问题
May 29 PHP
php集成动态口令认证
Jul 21 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
Oct 25 PHP
Yii2框架BootStrap样式的深入理解
Nov 07 PHP
PHP+Ajax实现的检测用户名功能简单示例
Feb 12 PHP
vmware linux系统安装最新的php7图解
Apr 14 PHP
thinkphp5使html5实现动态跳转的例子
Oct 16 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程序效率优化的一些策略小结
2010/07/17 PHP
PHP中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
PHP依赖倒置(Dependency Injection)代码实例
2014/10/11 PHP
php实现删除指定目录下相关文件的方法
2014/10/20 PHP
PHP统计目录大小的自定义函数分享
2014/11/18 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
2016/09/22 PHP
Js切换功能的简单方法
2010/11/23 Javascript
Jquery实现带动画效果的经典二级导航菜单
2013/03/22 Javascript
javascript中的document.open()方法使用介绍
2013/10/09 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
JQuery选择器、过滤器大整理
2015/05/26 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
详细分析单线程JS执行问题
2017/11/22 Javascript
微信小程序登录换取token的教程
2018/05/31 Javascript
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
nodejs二进制与Buffer的介绍与使用
2019/07/11 NodeJs
基于Vue el-autocomplete 实现类似百度搜索框功能
2019/10/25 Javascript
使用python在校内发人人网状态(人人网看状态)
2014/02/19 Python
详解Django中Request对象的相关用法
2015/07/17 Python
unittest+coverage单元测试代码覆盖操作实例详解
2018/04/04 Python
Pycharm之快速定位到某行快捷键的方法
2019/01/20 Python
css3进阶之less实现星空动画的示例代码
2019/09/10 HTML / CSS
New Balance天猫官方旗舰店:始于1906年,百年慢跑品牌
2017/11/15 全球购物
MYPROTEIN澳大利亚官方网站:欧洲运动营养品牌
2019/06/26 全球购物
法国床上用品商店:La Compagnie du lit
2019/12/26 全球购物
见习期自我鉴定
2013/11/07 职场文书
大学毕业生最详细的自我评价分享
2013/11/18 职场文书
厨师长岗位职责
2014/03/02 职场文书
10的分与合教学反思
2014/04/30 职场文书
标准版离职证明书
2014/09/12 职场文书
四风对照检查材料思想汇报
2014/09/20 职场文书
志愿者事迹材料
2014/12/26 职场文书
应届生求职自荐信范文
2015/03/04 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
pycharm无法安装cv2模块问题
2022/05/20 Python