PHP文件鎖類防止并發(fā)

對于商品搶購等并發(fā)場景下,可能會出現(xiàn)超賣的現(xiàn)象,這時就需要解決并發(fā)所帶來的這些問題了。在PHP語言中并沒有原生的提供并發(fā)的解決方案,因此就需要借助其他方式來實現(xiàn)并發(fā)控制。

方案一:使用文件鎖排它鎖
方案二:使用MySQL數(shù)據(jù)庫提供的悲觀鎖
方案三:使用隊列
方案四:使用Redis/Memcached

下面做種介紹下方案一,文件鎖:

  • flock函數(shù)用于獲取文件的鎖,這個鎖同時只能被一個線程獲取到,其它沒有獲取到鎖的線程要么阻塞,要么獲取失敗。flock()函數(shù)鎖定或釋放文件 若成功,則返回 true。若失敗,則返回 false
  • flock($fp,lock,block); block 若設(shè)置為true 則當進行鎖定時阻擋其他進程

LOCK_SH 建立共享鎖定。多個進程可同時對同一個文件作共享鎖定。
LOCK_EX 建立互斥鎖定。一個文件同時只有一個互斥鎖定。
LOCK_UN 解除文件鎖定狀態(tài)。
LOCK_NB 無法建立鎖定時,不阻斷。通常與LOCK_SH或LOCK_EX 做OR(|)組合。

文件鎖一個簡單的封裝類如下:

/**
 * 用于解決PHP在并發(fā)時候的鎖控制,不同的鎖之間并行執(zhí)行,類似mysql innodb的行級鎖
 */
class FileLock
{
    //文件鎖存放路徑
    private $path = '';
    //文件句柄
    private $fp = '';
    //鎖文件
    private $lockFile = '';
    /**
     * 構(gòu)造函數(shù)
     * @param string $path 鎖的存放目錄
     * @param string $name 鎖 KEY
     */
    public function __construct($name, $path = '')
    {
        if (empty($path)) {
            $this->path = dirname(__FILE__) . '/';
        } else {
            $this->path = $path;
        }

        $this->lockFile = $this->path . md5($name) . '.lock';
    }

    /**
     * 加鎖
     */
    public function lock()
    {
        $this->fp = fopen($this->lockFile, 'a+');
        if ($this->fp === false) {
            return false;
        }
        //LOCK_EX 獲取獨占鎖
        //LOCK_NB 無法建立鎖定時,不阻塞
        return flock($this->fp, LOCK_EX | LOCK_NB);
    }

    /**
     * 解鎖
     */
    public function unlock()
    {
        if ($this->fp !== false) {
            @flock($this->fp, LOCK_UN);
            clearstatcache();
        }
        @fclose($this->fp);
        @unlink($this->lockFile);
    }
}

文件鎖類使用示例:

$userid   = 21;
$article_id = 108;

//對業(yè)務(wù)請求加鎖
$lock    = new FileLock($userid . $article_id);
$lockResult = $lock->lock();

if (!$lockResult) {
    echo '當前請求速度過快,請稍后訪問!';
    $lock->unlock();
    exit;
}

/*
正常的業(yè)務(wù)邏輯處理
 */

//業(yè)務(wù)邏輯處理完畢解鎖
$lock->unlock();

Refer:
http://nearby.wang/s_64.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容