結構代碼php
public function index(){ $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX)) { // 處理商品數據 flock($fp,LOCK_UN); } fclose($fp); }
概述:數據庫
1.首先,讀寫方式打開或者建立文件lock.txt文件併發
2.給lock.txt文件上 "獨佔鎖",上鎖成功後就能夠進行下一步"處理訂單商品數據了"app
3.處理完數據後,要"釋放鎖」,以及fclose關閉打開的文件this
注意:給文件「獨佔鎖」後,若是再沒有裏面的「釋放鎖」,就沒有下一個"輪迴" spa
fopen詳細介紹:http://www.w3school.com.cn/php/func_filesystem_fopen.asp指針
flock詳細介紹:http://www.w3school.com.cn/php/func_filesystem_flock.aspcode
fclose詳細介紹:http://www.w3school.com.cn/php/func_filesystem_fclose.aspblog
詳細代碼io
namespace app\index\controller; use think\Controller; use think\Cache; class Index extends Controller { /** * 首頁 * */ public function index(){ $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX)) //鎖定當前指針,,, { //..處理訂單 $stock = $this->findStock(); if($stock > 0){ $this->setDec(); }else{ return '搶購失敗'; } return $stock; flock($fp,LOCK_UN); } fclose($fp); } /** * 查詢數據庫庫存 * */ public function findStock(){ $res = db('info')->where('id',1)->field('stock')->lock(true)->find(); return $res['stock']; } /** * 減小庫存操做 * */ public function setDec(){ $res = db('info')->where('id',1)->setDec('stock',1); return $res; } }
總結有點:
1.能夠解決併發問題,庫存爲負數的狀況。
2.併發是,你們都在等待。當全部併發結束後,纔會得到跳轉(這也是缺點,若是處理1000條併發,須要時間15s,那麼全部參加的人都須要等待15s後才進入下一個頁面)
非阻塞模式
結構代碼,與阻塞模式不一樣的地方 LOCK_NB (若是不但願 flock() 在鎖定時堵塞,則給 lock 加上 LOCK_NB)
代碼:
public function index(){ $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX | LOCK_NB)) { $stock = $this->findStock(); if($stock > 0){ $this->setDec(); }else{ return '搶購失敗'; } $this->setDec(); return $stock; flock($fp,LOCK_UN); } else { echo "搶購失敗,要再也不試試"; } fclose($fp); }
總結:
1.相比阻塞模式的時間等待,非阻塞模式則更加人性化不少
2.若是有有不少人都進入搶購,人太多就會直接進入第二個動做(「搶購失敗界面」)。部分人就會進入第一個動做(「搶購候選名單」), 下一個步驟1.搶購成功 或者2 搶購失敗