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简单系统查询模块代码打包下载
Jun 07 PHP
PHP Zip解压 文件在线解压缩的函数代码
May 26 PHP
PHP 读取大文件的X行到Y行内容的实现代码
Jun 24 PHP
PHP内核探索:变量概述
Jan 30 PHP
PHP对文件进行加锁、解锁实例
Jan 23 PHP
php强制更新图片缓存的方法
Feb 11 PHP
php使用类继承解决代码重复的问题
Feb 11 PHP
从性能方面考虑PHP下载远程文件的3种方法
Dec 29 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
May 22 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
Jun 13 PHP
PHP设计模式之建造者模式(Builder)原理与用法案例详解
Dec 12 PHP
Aliyun Linux 编译安装 php7.3 tengine2.3.2 mysql8.0 redis5的过程详解
Oct 20 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
星际实力自我测试
2020/03/04 星际争霸
DIY实用性框形天线
2021/03/02 无线电
Yii中创建自己的Widget实例
2016/01/05 PHP
PHP使用反射机制实现查找类和方法的所在位置
2016/04/22 PHP
Laravel框架实现简单的学生信息管理平台案例
2019/05/07 PHP
PHP FileSystem 文件系统常用api整理总结
2019/07/12 PHP
自动检查并替换文本框内的字符
2006/06/30 Javascript
用javascript父窗口控制只弹出一个子窗口
2007/04/10 Javascript
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
JavaScript的递归之递归与循环示例介绍
2013/08/05 Javascript
Javascript对象属性方法汇总
2013/11/21 Javascript
jQuery实现简单的列表式导航菜单效果代码
2015/08/31 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
2015/11/25 Javascript
Js实现简单的小球运动特效
2016/02/18 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
微信小程序 条件渲染详解
2016/10/09 Javascript
利用angularjs1.4制作的简易滑动门效果
2017/02/28 Javascript
详解Immutable及 React 中实践
2018/03/01 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
手动下载Chrome并解决puppeteer无法使用问题
2018/11/12 Javascript
Vue中通过属性绑定为元素绑定style行内样式的实例代码
2020/04/30 Javascript
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
[02:12]DOTA2英雄基础教程 变体精灵
2013/12/16 DOTA
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
2019/07/06 Python
Python将string转换到float的实例方法
2019/07/29 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
2019/11/08 Python
Django xadmin开启搜索功能的实现
2019/11/15 Python
Django Form and ModelForm的区别与使用
2019/12/06 Python
linux面试题参考答案(11)
2016/11/26 面试题
班主任对学生的评语
2014/04/26 职场文书
网络编辑求职信
2014/04/30 职场文书
品牌推广策划方案
2014/05/28 职场文书
升学宴学生致辞
2015/09/29 职场文书
宝宝满月宴答谢词
2015/09/30 职场文书
Python使用PyYAML库读写yaml文件的方法
2022/04/06 Python