Mysql的鎖機制與PHP檔案鎖處理高並發簡單思路

來源:互聯網
上載者:User

標籤:flock   root   blob   localhost   資源   代碼   table   ued   line   

以購買商品舉例:

① 從資料庫擷取庫存的數量。

② 檢查一下庫存的數量是否充足。

③ 庫存的數量減去買家購買的數量(以每個使用者購買一個為例)。

④ 最後完成購買。

僅僅這幾行邏輯代碼在並發的情況下會出現問題,自己可以想象一下。

這裡暫時就不測試了,下面會針對並發的處理給出測試結果。

建立表:

CREATE TABLE `warehouse` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘id‘,  `stock` int(11) NOT NULL DEFAULT ‘0‘ COMMENT ‘庫存‘,  PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
第一種方案,使用Mysql的鎖(跟表引擎沒有關係)。

共用鎖定:所有人可以讀一個資源,但只有擷取鎖的人可以操作;

排它鎖:只有獲得所的對象可以操作資源,其他的不能操作,讀都不可以。

文法:

LOCK TABLE a READ,b WRITE,c READ,d WRITE;(可以鎖多張表,在鎖表的過程中只能操作被鎖的表,不能操作其他表)。UNLOCK TABLES;(釋放表)。
@$mysql = mysql_connect(‘localhost‘,‘root‘,‘‘);mysql_query(‘set names utf8‘);mysql_select_db(‘test‘);mysql_query(‘LOCK TABLE `warehouse` WRITE‘);  //鎖表之後同一時間只有一個人能操作,也就是只有一個人能擷取到鎖$sql = ‘SELECT `stock` FROM warehouse‘;$res = mysql_query($sql);$row= mysql_fetch_array($res);$stock = $row[0];if( $stock < 1) {    die(‘庫存不足‘);}else{    $new_stock = intval($stock - 1);    mysql_query(‘UPDATE warehouse SET `stock` = ‘.$new_stock);    mysql_query(‘UPDATE TABLES‘);}

鎖表的缺點是:會出現阻塞,如果同時鎖多張表的話,還會影響整個網站相關表的載入。

第二種方案,使用PHP的檔案鎖。

特點:當調用flock鎖一個檔案時,如果沒有擷取鎖,直接返回FALSE,不會出現阻塞。

排它鎖:flock($fp,LOCK_EX);

共用鎖定:flock($fp,LOCK_SH);

釋放鎖:flock($fp,LOCK_UN);

@$mysql = mysql_connect(‘localhost‘,‘root‘,‘‘);mysql_query(‘set names utf8‘);mysql_select_db(‘test‘);$fp = fopen(‘./lock.txt‘,‘r‘);$try = 10;  //聲明一個變數表示要擷取的次數,防止死迴圈do{    $lock = flock($fp, LOCK_EX);    if(!$lock)        usleep(5000); //如果沒有擷取到鎖,釋放CPU,休息5000毫秒}while(!$lock && --$try >=0 );    if($lock) {    $sql = ‘SELECT `stock` FROM warehouse‘;    $res = mysql_query($sql);    $row = mysql_fetch_array($res);    $stock = $row[0];    if( $stock < 1) {        die(‘庫存不足‘);    }else{        $new_stock = intval($stock - 1);        mysql_query(‘UPDATE warehouse SET `stock` = ‘.$new_stock);    }}else{  die(‘系統繁忙!‘);}
第三種方案,簡單的SQL語句就可以避免倉庫為負數。
@$mysql = mysql_connect(‘localhost‘,‘root‘,‘‘);mysql_query(‘set names utf8‘);mysql_select_db(‘test‘);mysql_query(‘UPDATE warehouse SET `stock` = `stock` -1 WHERE `stock` > 0‘);  //可以避免庫存為負數

測試的方法是,找到Apache下的ab.exe,拖入CMD終端,然後輸入指定參數測試。

具體參數說明Google一下你就知道,比如耗時之類的...這裡不做詳細說明。

PS:Mysql的表鎖和PHP的檔案鎖在應對並發數量上也有差別,自己可以多測試。總之方案還有很多

Mysql的鎖機制與PHP檔案鎖處理高並發簡單思路

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.