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 adodb分页实现代码
Mar 19 PHP
检查php文件中是否含有bom的函数
May 31 PHP
php将字符串转化成date存入数据库的两种方式
Apr 28 PHP
PHP解决URL中文GBK乱码问题的两种方法
Jun 03 PHP
使用Huagepage和PGO来提升PHP7的执行性能
Nov 30 PHP
PHP引用的调用方法分析
Apr 25 PHP
php 变量引用与变量销毁机制详细介绍
Dec 05 PHP
PHP编程实现计算抽奖概率算法完整实例
Aug 09 PHP
微信公众号开发之获取位置信息php代码
Jun 13 PHP
PHP单例模式模拟Java Bean实现方法示例
Dec 07 PHP
PHP利用百度ai实现文本和图片审核
May 08 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
Oct 11 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 静态化实现代码
2009/03/20 PHP
phpmyadmin打开很慢的解决方法
2014/04/21 PHP
PHP文件上传处理案例分析
2016/10/15 PHP
PHP读取XML格式文件的方法总结
2017/02/27 PHP
Yii框架日志操作图文与实例详解
2019/09/09 PHP
php array 转json及java 转换 json数据格式操作示例
2019/11/13 PHP
Javascript 的addEventListener()及attachEvent()区别分析
2009/05/21 Javascript
jQuery实现拖拽效果插件的方法
2015/03/23 Javascript
Jquery使用val方法读写value值
2015/05/18 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
2015/12/03 Javascript
设计模式中的facade外观模式在JavaScript开发中的运用
2016/05/18 Javascript
js轮盘抽奖实例分析
2020/04/17 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
2016/09/05 Javascript
微信开发 消息推送实现代码
2016/10/21 Javascript
JavaScript中闭包的详解
2017/04/01 Javascript
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
JavaScript中的this/call/apply/bind的使用及区别
2020/03/06 Javascript
vue+高德地图实现地图搜索及点击定位操作
2020/09/09 Javascript
[55:39]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第二场 1月19日
2021/03/11 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
vue.js实现输入框输入值内容实时响应变化示例
2018/07/07 Python
Python3 批量扫描端口的例子
2019/07/25 Python
python实现静态服务器
2019/09/05 Python
50行Python代码实现视频中物体颜色识别和跟踪(必须以红色为例)
2019/11/20 Python
css3学习心得分享
2013/08/19 HTML / CSS
远程调用的原理
2014/07/05 面试题
解释下面关于J2EE的名词
2013/11/15 面试题
招商业务员岗位职责
2013/12/16 职场文书
机电职业生涯规划书范文
2014/03/08 职场文书
动画设计系毕业生求职信
2014/07/15 职场文书
人口与计划生育目标管理责任书
2014/07/29 职场文书
大班下学期个人总结
2015/02/13 职场文书
2015年幼儿园中班工作总结
2015/04/25 职场文书
一文搞懂Python Sklearn库使用
2021/08/23 Python
Nginx反向代理、重定向
2022/04/13 Servers