MySQL鎖機制和PHP鎖機制

模擬準備–如何模擬高并發訪問一個腳本:apache安裝文件的bin/ab.exe可以模擬并發量 -c 模擬多少并發量 -n 一共請求多少次 http://請求的腳本
例如:cmd: apache安裝路徑/bin/ab.exe -c 10 -n 10 http://web.test.com/test.php

【切入正題】
mysql中的鎖:
語法 :
lock table 表名1 read|write, 表名2 read|write ……………… 【鎖表】
unlock tables? 【釋放表】

Read:讀鎖|共享鎖 : 所有的客戶端只能讀這個表不能寫這個表
Write:寫鎖|排它鎖: 所有當前鎖定客戶端可以操作這個表,其他客戶端只能阻塞
注意:在鎖表的過程中只能操作被鎖定的表,如果要操作其他表,必須把所有要操作的表都鎖定起來!

PHP中的文件鎖 (鎖的是文件,不是表)
文件鎖的文件與表有什么關系?:一點關系也沒有,與令牌相似,誰拿到誰操作。所以表根本沒鎖。
測試時,有個文件就行,叫什么名無所謂

總結:
項目中應該只使用PHP中的文件鎖,盡量避免鎖表,因為如果表被鎖定了,那么整個網站中所有和這個表相關的功能都被拖慢了(例如:前臺很多用戶一直下訂單,商品表mysql鎖表,其他與商品表相關的操作一直處于阻塞狀態【讀不出來商品表】,因為一個功能把整個網站速度拖慢)。

我的一個項目就是O2O外賣,中午12-2點,晚上6點都是訂單高并發時,這種情況下,MySQL鎖顯然是不考慮的,用戶體驗太差。其實根據實際的需求,外賣可以不用設計庫存量的,當然除了秒殺活動模塊還是需要php文件鎖的。

應用場景:
1. 高并發下單時,減庫存量時要加鎖
2. 高并發搶單、搶票時要使用

MySQL鎖示例代碼:

<?php /**  模擬秒殺活動-- 商品100件  CREATE TABLE a  (      id int comment &#39;模擬100件活動商品的數量&#39;  );  INSERT INTO a VALUES(100);  模仿:以10的并發量訪問這個腳本!    使用apache自帶的ab.exe軟件   */  error_reporting(0);  mysql_connect(&#39;localhost&#39;,&#39;root&#39;,&#39;admin123&#39;);  mysql_select_db(&#39;test&#39;);  # mysql 鎖  mysql_query(&#39;LOCK TABLE a WRITE&#39;);// 只有一個客戶端可以鎖定表,其他客戶端阻塞在這  $rs = mysql_query(&#39;SELECT id FROM a&#39;);  $id = mysql_result($rs, 0, 0);  if($id >?0)  {  ????--$id;  ????mysql_query('UPDATE?a?SET?id='.$id);  }  #?mysql?解鎖  mysql_query('UNLOCK?TABLES');

PHP文件鎖示例代碼:

<?php /**  模擬秒殺活動-- 商品100件  CREATE TABLE a  (      id int comment &#39;模擬100件活動商品的數量&#39;  );  INSERT INTO a VALUES(100);  模仿:以10的并發量訪問這個腳本!    使用apache自帶的ab.exe軟件   */  error_reporting(0);  mysql_connect(&#39;localhost&#39;,&#39;root&#39;,&#39;admin123&#39;);  mysql_select_db(&#39;test&#39;);  # php中的文件鎖  $fp = fopen(&#39;./a.lock&#39;, &#39;r&#39;); // php的文件鎖和表沒關系,隨便一個文件即可  flock($fp, LOCK_EX);// 排他鎖  $rs = mysql_query(&#39;SELECT id FROM a&#39;);  $id = mysql_result($rs, 0, 0);  if($id >?0)  {  ????--$id;  ????mysql_query('UPDATE?a?SET?id='.$id);  }  #?php的文件鎖,釋放鎖  flock($fp,?LOCK_UN);  fclose($fp);
? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享