美文网首页
PHP文件锁类防止并发

PHP文件锁类防止并发

作者: finally_y | 来源:发表于2018-02-02 18:22 被阅读0次

对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了。在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制。

方案一:使用文件锁排它锁
方案二:使用MySQL数据库提供的悲观锁
方案三:使用队列
方案四:使用Redis/Memcached

下面做种介绍下方案一,文件锁:

  • flock函数用于获取文件的锁,这个锁同时只能被一个线程获取到,其它没有获取到锁的线程要么阻塞,要么获取失败。flock()函数锁定或释放文件 若成功,则返回 true。若失败,则返回 false
  • flock($fp,lock,block); block 若设置为true 则当进行锁定时阻挡其他进程

LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,不阻断。通常与LOCK_SH或LOCK_EX 做OR(|)组合。

文件锁一个简单的封装类如下:

/**
 * 用于解决PHP在并发时候的锁控制,不同的锁之间并行执行,类似mysql innodb的行级锁
 */
class FileLock
{
    //文件锁存放路径
    private $path = '';
    //文件句柄
    private $fp = '';
    //锁文件
    private $lockFile = '';
    /**
     * 构造函数
     * @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;

//对业务请求加锁
$lock    = new FileLock($userid . $article_id);
$lockResult = $lock->lock();

if (!$lockResult) {
    echo '当前请求速度过快,请稍后访问!';
    $lock->unlock();
    exit;
}

/*
正常的业务逻辑处理
 */

//业务逻辑处理完毕解锁
$lock->unlock();

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

相关文章

  • PHP文件锁类防止并发

    对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了。在PHP语言中并没有原生的提...

  • PHP使用redis锁防止并发访问

    锁必须具备的特点 1、互斥: 任意时刻, 只能有一个客户端获得锁 2、不会死锁: 客户端持有锁期间崩溃, 没有主动...

  • 什么是锁?

    锁的相关概念 锁被设计出来的的初衷是为了处理并发访问,两个请求访问相同资源时候,为了防止发生冲突,创建一个锁文件,...

  • php+redis消息队列实现抢购功能

    实现功能: 基于redis队列,防止高并发的超卖 基于mysql的事务加排它锁,防止高并发的超卖基于redis队列...

  • PHP生成二维码

    phpqrcode.php(php类文件)

  • if ( ! defined('BASEPATH'

    为了防止框架内特定的php文件被直接访问,防止跨域攻击。

  • 分布式事务 --悲观并发控制(两阶段锁)

    两阶段锁(Two-Phase Locking,2PL)是一种悲观并发控制,它使用锁来防止并发事务对数据的干扰,以实...

  • php引用类文件

  • php 使用redis锁限制并发访问类

    1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用...

  • redis 面试题

    技巧:1、redis + lua 解决高并发场景下的写操作2、redis 分布式锁,防止并发写3、redis 队列...

网友评论

      本文标题:PHP文件锁类防止并发

      本文链接:https://www.haomeiwen.com/subject/gwiezxtx.html