php文件阻塞锁实现防止并发请求

流氓凡 技术分享 2020-10-09 6.5 K 0

小项目应用还是比较实用的,当然最好还是借助于Redis来做锁操作。下面是文件阻塞锁操作类:

class Lock
{
    // 文件锁资源树
    static $resource = [];

    /**
     * 加锁
     * @param $uniqueId
     * @return bool
     */
    public static function lockUp($uniqueId)
    {
        static::$resource[$uniqueId] = fopen(static::getFilePath($uniqueId), 'w+');
        return flock(static::$resource[$uniqueId], LOCK_EX);
    }

    /**
     * 解锁
     * @param $uniqueId
     * @return bool
     */
    public static function unLock($uniqueId)
    {
        if (!isset(static::$resource[$uniqueId])) return false;
        flock(static::$resource[$uniqueId], LOCK_UN);
        fclose(static::$resource[$uniqueId]);
        return static::deleteFile($uniqueId);
    }

    /**
     * 获取锁文件的路径
     * @param $uniqueId
     * @return string
     */
    private static function getFilePath($uniqueId)
    {
        $dirPath = RUNTIME_PATH . 'lock/';
        !is_dir($dirPath) && mkdir($dirPath, 0755, true);
        return $dirPath . md5($uniqueId) . '.lock';
    }

    /**
     * 删除锁文件
     * @param $uniqueId
     * @return bool
     */
    private static function deleteFile($uniqueId)
    {
        $filePath = static::getFilePath($uniqueId);
        return file_exists($filePath) && unlink($filePath);
    }
}

使用方法范例:

public function help_cut($task_id)
{
    // 加阻塞锁, 防止并发
    Lock::lockUp($goods_id);
    /**
        这里进行业务处理
    **/
    
    // 解除并发锁
    Lock::unLock($goods_id);

}


评论