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作的文本留言本的例子(四)
Oct 09 PHP
关于mysql 字段的那个点为是定界符
Jan 15 PHP
PHP获取类中常量,属性,及方法列表的方法
Apr 09 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
Jun 12 PHP
php操作csv文件代码实例汇总
Sep 22 PHP
ThinkPHP有变量的where条件分页实例
Nov 03 PHP
smarty实现多级分类的方法
Dec 05 PHP
php中ob函数缓冲机制深入理解
Aug 03 PHP
PHP闭包函数传参及使用外部变量的方法
Mar 15 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
Apr 04 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
Aug 10 PHP
Ajax+PHP实现的分类列表框功能示例
Feb 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
全国FM电台频率大全 - 30 宁夏回族自治区
2020/03/11 无线电
PHP 中的类
2006/10/09 PHP
深入理解php的MySQL连接类
2013/06/07 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
2016/11/12 PHP
使用Laravel中的查询构造器实现增删改查功能
2019/09/03 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
基于jquery的划词搜索实现(备忘)
2010/09/14 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
jQuery中slideUp 和 slideDown 的点击事件
2015/02/26 Javascript
JavaScript创建闭包的两种方式的优劣与区别分析
2015/06/22 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
2016/06/17 Javascript
BootStrap tab选项卡使用小结
2020/08/09 Javascript
js遮罩效果制作弹出注册界面效果
2017/01/25 Javascript
vue代码分割的实现(codesplit)
2018/11/13 Javascript
JavaScript使用小插件实现倒计时的方法讲解
2019/03/11 Javascript
layui下拉框获取下拉值(select)的例子
2019/09/10 Javascript
easyUI使用分页过滤器对数据进行分页操作实例分析
2020/06/01 Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
2020/07/13 Javascript
vue3弹出层V3Popup实例详解
2021/01/04 Vue.js
浅谈Python程序与C++程序的联合使用
2015/04/07 Python
使用Python制作获取网站目录的图形化程序
2015/05/04 Python
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
Python实现的圆形绘制(画圆)示例
2018/01/31 Python
pandas中的DataFrame按指定顺序输出所有列的方法
2018/04/10 Python
PyCharm Community安装与配置的详细教程
2020/11/24 Python
利用纯html5绘制出来的一款非常漂亮的时钟
2015/01/04 HTML / CSS
移动端Html5中百度地图的点击事件
2019/01/31 HTML / CSS
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
车间操作工岗位职责
2013/12/19 职场文书
安全生产隐患排查制度
2015/08/05 职场文书
初中班主任教育随笔
2015/08/15 职场文书
2016学校先进集体事迹材料
2016/02/29 职场文书
女人创业励志语录,句句蕴含能量,激发你的潜能
2019/08/20 职场文书
Redis中缓存穿透/击穿/雪崩问题和解决方法
2021/12/04 Redis
CI Games宣布《堕落之王2》使用虚幻引擎5制作 预计将于2023年正式发售
2022/04/11 其他游戏