PHP利用Mysql锁解决高并发问题

2022-10-11 21:20:41 218 0
魁首哥

目录

  • 概述
  • 应用场景
  • 不使用事务的时候并发问题
  • 使用mysql事务和锁解决并发商品超卖问题
  • php7进阶到架构师相关阅读

概述

这是关于php进阶到架构之 PHP核心技术与实践 系列学习课程:PHP利用MYSQL锁解决高并发超卖问题

学习目标

PHP利用Mysql锁解决高并发问题

解决类似商城秒杀高并发导致库存变成负数的问题

应用场景

在商城秒杀应用中,高并发时,在没有事务的时候,商品会出现超卖的情况,即商品的库存出现负数的情况


创建库存管理表

创建订单管理表

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)

库存数变成了-2,变成了负数,即出现了超卖现象

使用mysql事务和锁解决并发商品超卖问题


代码调整如下

 $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();//回滚
    }
}  

例如ab模拟并发测试之后,查看结果如下:

 mysql> select * from storage;
+----+--------+
| id | number |
+----+--------+
| 1 | 0 |
+----+------
--+
1 row in set (0.00 sec)  

利用mysql锁以后,库存数没有变成负数,即没有出现商品超卖的情况

php7进阶到架构师相关阅读

最后,欢迎大家留言补充,讨论~~~
喜欢小编的话,欢迎点赞、收藏和关注哦~~~///(^v^)\\\~~~

收藏
分享
海报
0 条评论
218
上一篇:python学习: 使用browsercookie从浏览器获取cookies 下一篇:php中mysqli_query函数的作用

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码