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
php开发文档 会员收费1期
Aug 14 PHP
php cli模式学习(PHP命令行模式)
Jun 03 PHP
php引用传值实例详解学习
Nov 06 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
Apr 14 PHP
mac下Apache + MySql + PHP搭建网站开发环境
Jun 02 PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 PHP
php 在字符串指定位置插入新字符的简单实现
Jun 28 PHP
php文件类型MIME对照表(比较全)
Oct 07 PHP
PHP多维数组元素操作类的方法
Nov 14 PHP
PHP使用GD库制作验证码的方法(点击验证码或看不清会刷新验证码)
Aug 15 PHP
php apache开启跨域模式过程详解
Jul 08 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
smarty 原来也不过如此~~呵呵
2006/11/25 PHP
Php图像处理类代码分享
2012/01/19 PHP
php合并数组中相同元素的方法
2014/11/13 PHP
简单理解PHP的面向对象编程方式
2016/05/17 PHP
PHP文件上传操作实例详解
2016/09/27 PHP
验证坐标在某坐标区域内php代码
2016/10/08 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
用YUI做了个标签浏览效果
2007/02/20 Javascript
javascript 表格排序和表头浮动效果(扩展SortTable)
2009/04/07 Javascript
javascript中"/"运算符常见错误
2010/10/13 Javascript
jQuery编写widget的一些技巧分享
2010/10/28 Javascript
JS打开图片另存为对话框实现代码
2012/12/26 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
js设置cookie过期当前时间减去一秒相当于立即过期
2014/09/04 Javascript
深入探寻seajs的模块化与加载方式
2015/04/14 Javascript
jquery实现简单的无缝滚动
2015/04/15 Javascript
jquery.serialize() 函数语法及简单实例
2016/07/08 Javascript
jQuery常见的选择器及用法介绍
2016/12/20 Javascript
Vue中使用vue-i18插件实现多语言切换功能
2018/04/25 Javascript
详解Vue.js iview实现树形权限表(可扩展表)
2018/09/30 Javascript
element el-input directive数字进行控制
2018/10/11 Javascript
vue+echarts实现中国地图流动效果(步骤详解)
2021/01/27 Vue.js
pymssql数据库操作MSSQL2005实例分析
2015/05/25 Python
如何使用python爬取csdn博客访问量
2016/02/14 Python
Python端口扫描简单程序
2016/11/10 Python
Python3 Click模块的使用方法详解
2020/02/12 Python
html+js 实现markdown编辑器效果
2019/10/23 HTML / CSS
上海期货面试题
2014/01/31 面试题
大学生毕业的自我鉴定
2013/11/13 职场文书
十佳班主任事迹材料
2014/01/18 职场文书
公司总经理岗位职责范本
2014/08/15 职场文书
殡葬服务心得体会
2014/09/11 职场文书
2014迎国庆标语大全
2014/09/19 职场文书
被告答辩状范文
2015/05/22 职场文书
英语投诉信范文
2015/07/03 职场文书
幼儿园语言教学反思
2016/02/23 职场文书