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 相关文章推荐
Zend公司全球首推PHP认证
Oct 09 PHP
用libtemplate实现静态网页生成
Oct 09 PHP
第十五节--Zend引擎的发展
Nov 16 PHP
深入PHP数据缓存的使用说明
May 10 PHP
php防注入,表单提交值转义的实现详解
Jun 10 PHP
PHPUnit安装及使用示例
Oct 29 PHP
PHP实现无限极分类图文教程
Nov 25 PHP
PHP实现的简单日历类
Nov 29 PHP
php将字符串转换成16进制的方法
Mar 17 PHP
YII Framework教程之异常处理详解
Mar 14 PHP
PHP递归删除多维数组中的某个值
Apr 17 PHP
Laravel 5.4.36中session没有保存成功问题的解决
Feb 19 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表单转换textarea换行符的方法
2010/09/10 PHP
关于尾递归的使用详解
2013/05/02 PHP
浅谈使用 PHP 进行手机 APP 开发(API 接口开发)
2014/08/11 PHP
php遍历删除整个目录及文件的方法
2015/03/13 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
jQuery 注意事项 与原因分析
2009/04/24 Javascript
javascript 跳转代码集合
2009/12/03 Javascript
jquery设置控件位置的方法
2013/08/21 Javascript
Javascript学习笔记之 函数篇(二) : this 的工作机制
2014/06/24 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
深入理解JavaScript系列(25):设计模式之单例模式详解
2015/03/03 Javascript
js中 javascript:void(0) 用法详解
2015/08/11 Javascript
有关Promises异步问题详解
2015/11/13 Javascript
jQuery的Cookie封装,与PHP交互的简单实现
2016/10/05 Javascript
JS搜狐面试题分析
2016/12/16 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
2017/07/13 Javascript
BootStrap的双日历时间控件使用
2017/07/25 Javascript
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
在vue中安装使用vux的教程详解
2018/09/16 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
在VUE style中使用data中的变量的方法
2020/06/19 Javascript
浅谈Python中的zip()与*zip()函数详解
2018/02/24 Python
利用python list完成最简单的DB连接池方法
2019/08/09 Python
python基于pdfminer库提取pdf文字代码实例
2019/08/15 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
OpenCV+Python3.5 简易手势识别的实现
2020/12/21 Python
HTML5之web workers_动力节点Java学院整理
2017/07/17 HTML / CSS
如何使用html5与css3完成google涂鸦动画
2012/12/16 HTML / CSS
罗技美国官网:Logitech美国
2020/01/22 全球购物
小区门卫岗位职责
2013/12/31 职场文书
家居装修公司创业计划书范文
2014/03/20 职场文书
好好学习保证书
2015/02/26 职场文书
2016优秀护士先进个人事迹材料
2016/02/25 职场文书
mysql数据插入覆盖和时间戳的问题及解决
2022/03/25 MySQL