• PHP利用Mysql锁解决高并发


    前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用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)

    
    <p>得到了订单共有<code>12</code>个,而库存表的库存也减到了<code>-2</code>,这显然不符合实际逻辑的;</p>
    <h5>下面我们来看利用数据库行锁来解决这个问题</h5>
    <blockquote>修改代码如下</blockquote>
    
    

    $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-&gt;query($sql);
    if($order_id)
    {
    
        $sql="update storage set `number`=`number`-1 WHERE id=1";
        if($pdo-&gt;query($sql))
        {
            $pdo-&gt;commit();//提交事务
        }
        else
        {
            $pdo-&gt;rollBack();//回滚
        }
    
    }
    else
    {
        $pdo-&gt;rollBack();//回滚
    }
    

    }

    
    <blockquote>查看结果</blockquote>
    

    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)

    
    <p>很明显在利用了mysql锁之后,对库存进行了有效的控制,很好的解决了第一段代码里面,因为并发引起的一些逻辑性的问题</p>
    
                    
                                                    
    原文地址:https://segmentfault.com/a/1190000016251947
  • 相关阅读:
    spring多个context:property-placeholder不生效问题
    JAVA中自定义properties文件介绍
    spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。
    web.xml文件头声明各个版本参考
    Java 组件化(gradle)
    阿里开源框架-JarsLink-【JAVA的模块化开发框架】
    二gradle创建SSM项目——Hello word
    一gradle创建SSM项目——依赖包
    微信开发学习总结(二)——微信开发入门
    js函数声明的三种方式
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9971630.html
Copyright © 2020-2023  润新知