歡迎來(lái)到深圳市志博科技有限公司網站!
您當前的(de)位置:深圳APP開發 > 新聞資訊 > APP開發資訊 >
人(rén)
已閱讀

用(yòng)PHP進行APP開發如何解決并發問題

來(lái)源:lexintech.com       發布時(shí)間:2017-09-26
在深圳的(de)APP開發公司中,用(yòng)PHP做(zuò)爲開發語言的(de)不少。雖然PHP語言适合做(zuò)互聯網産品,特别是web産品,在成本和(hé)效率上都有一定優勢。但是并發量的(de)問題,始終是PHP的(de)弱勢。比如開發一個(gè)商城(chéng),對(duì)于商品搶購(gòu)等并發場(chǎng)景下(xià),可(kě)能會出現超賣的(de)現象,這(zhè)時(shí)就需要解決并發所帶來(lái)的(de)這(zhè)些問題了(le)。在PHP語言中并沒有原生的(de)提供并發的(de)解決方案,那怎麽辦呢(ne),這(zhè)就需要借助其他(tā)方式來(lái)實現并發控制。
 
用(yòng)PHP進行APP開發
 
方案一:使用(yòng)文件鎖排它鎖
 
flock函數用(yòng)于獲取文件的(de)鎖,這(zhè)個(gè)鎖同時(shí)隻能被一個(gè)線程獲取到,其它沒有獲取到鎖的(de)線程要麽阻塞,要麽獲取失敗。
在獲取到鎖的(de)時(shí)候,先查詢庫存,如果庫存大(dà)于0,則進行下(xià)訂單操作,減庫存,然後釋放鎖。
 
 
方案二:使用(yòng)MySQL數據庫提供的(de)悲觀鎖
 
Innodb存儲引擎支持行級鎖,當某行數據被鎖定時(shí),其他(tā)進程不能對(duì)這(zhè)行數據進行操作。
先查詢并鎖定行:select stock_num from table where id=1 for update
if(stock_num > 0){
//下(xià)訂單
update table set stock_num=stock-1 where id=1
}
 
方案三:使用(yòng)隊列
 
将用(yòng)戶的(de)下(xià)單請求依次存入一個(gè)隊列中,後台用(yòng)一個(gè)單獨的(de)進程處理(lǐ)隊列中的(de)下(xià)單請求。
 
方案四:使用(yòng)Redis
 
redis的(de)操作都是原子性的(de),可(kě)以将商品的(de)庫存存入redis中,下(xià)單之前對(duì)庫存進行decr操作,如果返回的(de)值大(dà)于等于0等可(kě)以下(xià)單,否則不能下(xià)單,這(zhè)種方式效率較高(gāo)
if(redis->get('stock_num') > 0){
stock_num = redis->decr('stock_num')
if(stock_num >= 0){
//下(xià)訂單
}else{
//庫存不足
}
}else{
//庫存不足
}
 
其他(tā)并發問題:
 
在現實應用(yòng)中,很多(duō)情況下(xià)會把數據存入緩存,當緩存失效時(shí),去數據庫取數據并重新設置緩存,如果這(zhè)時(shí)并發量很大(dà),會有很多(duō)進程同時(shí)去數據庫取數據,導緻很多(duō)請求穿透到數據庫,而使數據庫奔潰,這(zhè)裏可(kě)用(yòng)文件鎖來(lái)解決。
 
[php] view plain copy
$data = $cache->get('key');
if(!$data){
$fp = fopen('lockfile');
if(flock($fp, LOCK_EX)){
$data = $cache->get('key');//拿到鎖後再次檢查緩存,這(zhè)時(shí)可(kě)能已經有了(le)
if(!$data){
$data = mysql->query();
$cache->set('key', $data);
}
flock($fp, LOCK_UN);
}
fclose($fp);
}
說到底,PHP要解決并發問題就必須要加鎖,各種方案的(de)本質其實都是加鎖。希望上面的(de)分(fēn)享能對(duì)您有所幫助。
 
APP開發 網站開發 産品設計 微信公衆号 APP開發公司 用(yòng)戶體驗 APP運營 微信小程序 産品經理(lǐ) 網站設計