php memcached互斥,PHP文件锁类防止并发

对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了。在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();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值