摘要:以購(gòu)買商品舉例從數(shù)據(jù)庫(kù)獲取庫(kù)存的數(shù)量。這里暫時(shí)就不測(cè)試了,下面會(huì)針對(duì)并發(fā)的處理給出測(cè)試結(jié)果。第二種方案,使用的文件鎖。特點(diǎn)當(dāng)調(diào)用鎖一個(gè)文件時(shí),如果沒有獲取鎖,直接返回,不會(huì)出現(xiàn)阻塞。的表鎖和的文件鎖在應(yīng)對(duì)并發(fā)數(shù)量上也有差別,自己可以多測(cè)試。
以購(gòu)買商品舉例:
① 從數(shù)據(jù)庫(kù)獲取庫(kù)存的數(shù)量。
② 檢查一下庫(kù)存的數(shù)量是否充足。
③ 庫(kù)存的數(shù)量減去買家購(gòu)買的數(shù)量(以每個(gè)用戶購(gòu)買一個(gè)為例)。
④ 最后完成購(gòu)買。
僅僅這幾行邏輯代碼在并發(fā)的情況下會(huì)出現(xiàn)問題,自己可以想象一下。
這里暫時(shí)就不測(cè)試了,下面會(huì)針對(duì)并發(fā)的處理給出測(cè)試結(jié)果。
創(chuàng)建表:
CREATE TABLE `warehouse` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT "id", `stock` int(11) NOT NULL DEFAULT "0" COMMENT "庫(kù)存", PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
第一種方案,使用Mysql的鎖(跟表引擎沒有關(guān)系)。
共享鎖:所有人可以讀一個(gè)資源,但只有獲取鎖的人可以操作;
排它鎖:只有獲得所的對(duì)象可以操作資源,其他的不能操作,讀都不可以。
語(yǔ)法:
LOCK TABLE a READ,b WRITE,c READ,d WRITE;(可以鎖多張表,在鎖表的過(guò)程中只能操作被鎖的表,不能操作其他表)。 UNLOCK TABLES;(釋放表)。 @$mysql = mysql_connect("localhost","root",""); mysql_query("set names utf8"); mysql_select_db("test"); mysql_query("LOCK TABLE `warehouse` WRITE"); //鎖表之后同一時(shí)間只有一個(gè)人能操作,也就是只有一個(gè)人能獲取到鎖 $sql = "SELECT `stock` FROM warehouse"; $res = mysql_query($sql); $row= mysql_fetch_array($res); $stock = $row[0]; if( $stock < 1) { die("庫(kù)存不足"); }else{ $new_stock = intval($stock - 1); mysql_query("UPDATE warehouse SET `stock` = ".$new_stock); mysql_query("UPDATE TABLES"); }
鎖表的缺點(diǎn)是:會(huì)出現(xiàn)阻塞,如果同時(shí)鎖多張表的話,還會(huì)影響整個(gè)網(wǎng)站相關(guān)表的加載。
第二種方案,使用PHP的文件鎖。
特點(diǎn):當(dāng)調(diào)用flock鎖一個(gè)文件時(shí),如果沒有獲取鎖,直接返回FALSE,不會(huì)出現(xiàn)阻塞。
排它鎖: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; //聲明一個(gè)變量表示要獲取的次數(shù),防止死循環(huán) 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("庫(kù)存不足"); }else{ $new_stock = intval($stock - 1); mysql_query("UPDATE warehouse SET `stock` = ".$new_stock); } flock($fp, LOCK_UN); fclose($fp); }else{ die("系統(tǒng)繁忙!"); }
第三種方案,簡(jiǎn)單的SQL語(yǔ)句就可以避免倉(cāng)庫(kù)為負(fù)數(shù)。
@$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"); //可以避免庫(kù)存為負(fù)數(shù)
測(cè)試的方法是,找到Apache下的ab.exe,拖入CMD終端,然后輸入指定參數(shù)測(cè)試。
具體參數(shù)說(shuō)明Google一下你就知道,比如耗時(shí)之類的...這里不做詳細(xì)說(shuō)明。
PS:Mysql的表鎖和PHP的文件鎖在應(yīng)對(duì)并發(fā)數(shù)量上也有差別,自己可以多測(cè)試??傊桨高€有很多
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/28172.html
摘要:行級(jí)鎖,頁(yè)級(jí)鎖,表級(jí)鎖。聞其名知其意,比較少見的是頁(yè)級(jí)鎖,它鎖定的是一組相鄰數(shù)據(jù)。排他鎖允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的讀寫。意向排他鎖事務(wù)打算給數(shù)據(jù)行加行排他鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的鎖。 廢話 本篇的名字簡(jiǎn)直可以起成《事務(wù)操作:從入門到放棄》。 力圖解決:在MySQL 5.5 版本及更高版本時(shí),使用事務(wù)的完整流程和細(xì)節(jié)記錄,而無(wú)需面對(duì)...
摘要:關(guān)于串行化與一致性的關(guān)系數(shù)據(jù)庫(kù)并發(fā)控制的基本目標(biāo)是確保事務(wù)的并發(fā)執(zhí)行不會(huì)導(dǎo)致數(shù)據(jù)庫(kù)一致性的丟失。該請(qǐng)求發(fā)送給并發(fā)控制管理器,只有并發(fā)控制管理器授予所需鎖后,事務(wù)才能繼續(xù)其操作。 全文主要參考數(shù)據(jù)庫(kù)系統(tǒng)概念一書以及mooc上戰(zhàn)德臣老師的數(shù)據(jù)庫(kù)課程 事務(wù)最基本的特性之一是隔離性,當(dāng)數(shù)據(jù)庫(kù)中有多個(gè)事務(wù)并發(fā)執(zhí)行的時(shí)候,隔離性不一定能保持。為了保持事務(wù)的隔離性,系統(tǒng)必須對(duì)并發(fā)事務(wù)之間的相互作用...
閱讀 3276·2021-11-10 11:35
閱讀 1477·2019-08-30 13:20
閱讀 1174·2019-08-29 16:18
閱讀 2207·2019-08-26 13:54
閱讀 2215·2019-08-26 13:50
閱讀 1009·2019-08-26 13:39
閱讀 2556·2019-08-26 12:08
閱讀 2008·2019-08-26 10:37