站長資訊網
        最全最豐富的資訊網站

        淺析php簡單操作mysql鎖機制

        淺析php簡單操作mysql鎖機制

        鎖機制
        共享鎖與排他鎖
        共享鎖(讀鎖):其他事務可以讀,但不能寫。
        排他鎖(寫鎖) :其他事務不能讀取,也不能寫。

        對于MySQL來說,有三種鎖的級別:頁級、表級、行級

        • 頁級的典型代表引擎為BDB。
        • 行級的典型代表引擎為INNODB。
        • 表級的典型代表引擎為MyISAM,MEMORY以及很久以前的ISAM。
        • BDB 存儲引擎采用的是頁面鎖(page-level locking),但也支持表級鎖
        • InnoDB 存儲引擎既支持行級鎖(row-level locking),也支持表級鎖,但默認情況下是采用行級鎖。
        • MyISAM 和 MEMORY 存儲引擎采用的是表級鎖

        相關免費學習推薦:php編程(視頻)

        1、MyISAM 表鎖

        MyISAM表級鎖模式:

        • 表共享讀鎖 (Table Read Lock):不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫請求;
        • 表獨占寫鎖 (Table Write Lock):會阻塞其他用戶對同一表的讀和寫操作;

        MyISAM加表鎖方法:

        • 用 LOCK TABLE 命令給 MyISAM 表顯式加鎖
        • LOCK TABLES real_table (READ|WRITE), insert_table (READ|WRITE); //加鎖
        • UNLOCK TABLES; //解鎖

        列子:
        比如有 account(id,name,cash),hero(number,name,country)這兩張表

        1. lock tables account read; 將account加為只讀鎖
          當前進程查詢:select * from hero;會報Table ‘hero’ was not locked with LOCK TABLES。
          當前進程更改其他表:update hero set name=“ss” where number=1; 會報Table ‘hero’ was not locked with LOCK TABLES
          當前進程更改表:update account set name=“ssss” where id=1;會報Table ‘account’ was locked with a READ lock and can’t be updated
          如果別mysql進程進來,可以查詢其他表和account,但不能更改account,會一直等待,需要釋放鎖才執行

        1.1PHP操作

        <?php/**  * Created by PhpStorm.  * User: Administrator  * Date: 2021/4/29 0029  * Time: 11:20  */$link = new mysqli('127.0.0.1', 'root', '123', 'db_school'); // 連接數據庫if(mysqli_connect_errno()){                                // 檢查連接錯誤     printf("連接失敗:%s<br>", mysqli_connect_error());     exit();}//(s1)$table = "account";$type = "read";$sql1 = "LOCK TABLES $table $type";$link->query($sql1);//處理邏輯//$sql1 = "select * from $table;";        //(s1)true//$sql1 = "select * from hero;";        //false//$sql1 = "update hero set name='ss' where number=1; ";     //false$sql1 = "update account set name='ssss' where id=1;";   //false$result = $link->query($sql1);var_dump($result);sleep(20);  //測試    //假設還沒釋放鎖,開啟cmd進mysql(s2)可以查詢,但不能執行更改和刪除操作,會等待這邊釋放鎖$link->query("unlock tables");    //取消全部的鎖//解鎖后正常操作//$result = $link -> query($sql1);//var_dump($result);$link->close();

        查詢表級鎖爭用情況
        show status like ‘Table%’;

        • Table_locks_immediate 指的是能夠立即獲得表級鎖的次數
        • Table_locks_waited 指的是不能立即獲取表級鎖而需要等待的次數

        2.InnoDB加鎖方法:

        對于普通 SELECT 語句,InnoDB 不會加任何鎖;只能在事務執行過程中使用加鎖
        鎖只有在執行commit或者rollback的時候才會釋放,并且所有的鎖都是在同一時刻被釋放。

        • 共享鎖(S):SELECT * FROM table_name WHERE … LOCK IN SHARE MODE。其他 session 仍然可以查詢記錄,并也可以對該記錄加 share mode 的共享鎖。但是如果當前事務需要對該記錄進行更新操作,則很有可能造成死鎖。大家都能讀,但是不能改,只有其中一個獨占共享鎖時候才能改;
        • 排他鎖(X):SELECT * FROM table_name WHERE … FOR UPDATE。其他 session 可以查詢該記錄,但是不能對該記錄加共享鎖或排他鎖,而是等待獲得鎖。我要改,你們都不能改,也不能讀
          #select … lock in share mode //共享鎖
          #select … for update //排他鎖
          ##在 MySQL 8.0 中
        • 共享鎖(S):SELECT * FROM table_name WHERE … FOR SHARE
        • 排他鎖(X):SELECT * FROM table_name WHERE … FOR UPDATE[NOWAIT|SKIP LOCKED]
          –NOWAIT:發現有鎖等待后會立即返回錯誤,不用等待鎖超時后報錯。
          –SKIP LOCKED:跳過被鎖定的行,直接更新其他行,但是這樣要注意是否會造成更新結果不符合預期。

        2.1PHP操作

        <?php/**  * Created by PhpStorm.  * User: Administrator  * Date: 2021/4/29 0029  * Time: 10:06  */$link = new mysqli('127.0.0.1', 'root', '123', 'db_school'); // 連接數據庫if(mysqli_connect_errno()){                                // 檢查連接錯誤     printf("連接失敗:%s<br>", mysqli_connect_error());     exit();}//案例1$id = 1; //明確指定主鍵,并且有此數據,row lock (行鎖)//$id = -1;   //明確指定主鍵,若查無此數據,無lock (無鎖)$link->autocommit(0);                   // 開始事務(s1)//FOR UPDATE僅適用于InnoDB,且必須在交易區塊(BEGIN/COMMIT)中才能生效。$sql = "select * from account where id=$id for update";$link->query($sql);/***  * 此時其他mysql進程可以查詢該記錄,但是不能對該記錄加共享鎖或排他鎖,而是等待獲得鎖。  *///(s1)可以進行更改,和查詢等操作//$sql1 = "update account set name='aaa' where id=$id;";  //進行更改//$sql1 = "select * from account where id=$id;";  //進行查詢$sql1 = "delete from account where id=$id;";  //進行刪除$result = $link -> query($sql1);var_dump($result);sleep(20); //測試    //假設還在事務處理中,開啟cmd進mysql(s2)執行更改和刪除操作,會等待這邊釋放鎖$link->commit();$link->close();

        查看正在被鎖定的的表
        show OPEN TABLES where In_use > 0;
        SHOW PROCESSLIST顯示哪些線程正在運行。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产精品久久久久国产A级| 麻豆精品久久精品色综合| 国产精品55夜色66夜色| 久久精品国产精品亚洲下载| 91精品全国免费观看青青| 免费精品精品国产欧美在线欧美高清免费一级在线 | 精品视频第一页| 日产精品久久久久久久性色| 久久久精品久久久久久| 国产精品99久久不卡| WWW国产精品内射老师| 人人妻人人澡人人爽人人精品97 | 午夜精品久久久久久中宇| 精品亚洲欧美中文字幕在线看| 亚洲精品人成在线观看| 国产麻豆一精品一AV一免费| 亚洲国产精品一区二区第一页 | 亚洲精品tv久久久久久久久| 日韩视频中文字幕精品偷拍| 久久精品国产99久久久香蕉 | 国产亚洲欧洲精品| 第一福利永久视频精品| 国产精品9999久久久久| 精品无码久久久久国产| 亚洲中文字幕无码久久精品1| 午夜三级国产精品理论三级 | 久久精品国产亚洲av影院| 午夜欧美精品久久久久久久| 无码人妻丰满熟妇精品区| 真实国产乱子伦精品视频| 在线观看国产精品普通话对白精品 | 亚洲精品在线视频| 一区二区三区精品高清视频免费在线播放 | 久久99精品久久只有精品 | 国产精品女人呻吟在线观看| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 亚洲中文字幕无码久久精品1| 无码日韩精品一区二区免费暖暖 | 无码精品国产VA在线观看DVD| 无码精品人妻一区二区三区人妻斩| 亚洲午夜成人精品电影在线观看|