標籤: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檔案鎖處理高並發簡單思路