美文网首页
MySQL锁机制和PHP锁机制

MySQL锁机制和PHP锁机制

作者: Mracale | 来源:发表于2020-08-07 19:20 被阅读0次

    模拟准备--如何模拟高并发访问一个脚本:
    apache安装文件的bin/ab.exe可以模拟并发量 -c 模拟多少并发量 -n 一共请求多少次 http://请求的脚本例如:

    cmd: apache安装路径/bin/ab.exe -c 10 -n 10 http://my.test.com/miao.php
    或者可以使用apache jmeter 、loaderunner之类的进行压测

    MYSQL中的锁:
    语法 :
    LOCK TABLE 表名1 READ|WRITE, 表名2 READ|WRITE ..................
    【锁表】UNLOCK TABLES
    【释放表】
    Read:读锁|共享锁 : 所有的客户端只能读这个表不能写这个表
    Write:写锁|排它锁: 所有当前锁定客户端可以操作这个表,其他客户端只能阻塞
    注意:在锁表的过程中只能操作被锁定的表,如果要操作其他表,必须把所有要操作的表都锁定起来!

    PHP中的文件锁 (锁的是文件,不是表)文件锁的文件与表有什么关系?:一点关系也没有,与令牌相似,谁拿到谁操作。所以表根本没锁。测试时,有个文件就行,叫什么名无所谓

    总结:项目中应该只使用PHP中的文件锁,尽量避免锁表,因为如果表被锁定了,那么整个网站中所有和这个表相关的功能都被拖慢了(例如:前台很多用户一直下订单,商品表mysql锁表,其他与商品表相关的操作一直处于阻塞状态【读不出来商品表】,因为一个功能把整个网站速度拖慢)。

    应用场景:
    高并发下单时,减库存量时要加锁
    高并发抢单、抢票时要使用

    MySQL锁示例代码:

    <?php  
    /** 
    模拟秒杀活动-- 商品100件 
    CREATE TABLE a 
    ( 
        id int comment '模拟100件活动商品的数量' 
    ); 
    INSERT INTO a VALUES(100); 
    模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件 
     */  
    error_reporting(0);  
    error_reporting(0);
    // 假定数据库用户名:root,密码:456852,数据库:test
    $con=mysqli_connect("localhost","root","456852","test"); 
    
    if (mysqli_connect_errno($con)){ 
        echo "连接 MySQL 失败: " . mysqli_connect_error(); 
    }
    
    # mysql 锁  
    mysqli_query($con,'LOCK TABLE a WRITE');// 只有一个客户端可以锁定表,其他客户端阻塞在这  
    $rs = mysqli_query($con,'SELECT id FROM a');
    $data = $rs->fetch_assoc();
    $id = 0;
    if (!empty($data)) {
        $id = $data['id'];
    }
    if($id > 0){
        --$id;
        mysqli_query($con,'UPDATE a SET id='.$id);  
    }
    //mysql 解锁  
    mysqli_query($con,'UNLOCK TABLES');  
    

    PHP锁示例代码:

    <?php
    /** 
    模拟秒杀活动-- 商品10件 
    CREATE TABLE a 
    ( 
        id int comment '模拟10件活动商品的数量' 
    ); 
    INSERT INTO a VALUES(100); 
    模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件 
     */
    
    error_reporting(0);
    // 假定数据库用户名:root,密码:456852,数据库:test
    $con=mysqli_connect("localhost","root","456852","test"); 
    if (mysqli_connect_errno($con)){ 
        echo "连接 MySQL 失败: " . mysqli_connect_error(); 
    }
    /**
        php中的文件锁
        php的文件锁和表没关系,随便一个文件即可,目的只是让一个请求进来
    **/
    $fp = fopen('./a.lock', 'r');
    flock($fp, LOCK_EX);// 排他锁  
      
    $rs = mysqli_query($con,'SELECT id FROM a');
    $data = $rs->fetch_assoc();
    $id = 0;
    if (!empty($data)) {
        $id = $data['id'];
    }
    if($id > 0){
        --$id;
        mysqli_query($con,'UPDATE a SET id='.$id);  
    }
    # php的文件锁,释放锁  
    flock($fp, LOCK_UN);
    fclose($fp);
    
    ?>
    

    相关文章

      网友评论

          本文标题:MySQL锁机制和PHP锁机制

          本文链接:https://www.haomeiwen.com/subject/molrrktx.html