PHP-Redis实现分布式乐观锁,悲观锁

3 篇文章 0 订阅

乐观锁悲观锁使用场景请看这篇
乐观锁悲观锁使用场景

一: 悲观锁

特性:
1:互斥性,一个线程获取后其他不能获取,等待或者返回false
2:不能死锁,超时应该自动释放
3:锁应该只能由加锁人解锁

下面是redis 实现的伪代码

/**
 * Class RedisLock
 * @package app\common\model
 */
class RedisLock  {
    private $redis;
    private $lock;
    public function __construct($redis)
    {
        $this->redis=$redis;
    }

    /**
     * @param $key 锁名
     * @param int $overtime 锁超时时间单位秒
     * @param int $waittime 等待超时时间,可能会阻塞线程,单位秒
     */
    public function lock($key,$overtime=5,$waittime=0){
        $time=microtime(true);
        //用随机字符串防止被别的线程删除
        $this->lock=rand_string(16);


        //参数 nx 代表key不存在才操作, ex 缓存有效时间
        $ok = $this->redis->set($key, $this->lock, array('nx', 'ex' => $overtime));
        if ($ok) {
            return $this->lock;
        }

        //循环获取,默认不等待
        while (microtime(true)-$time>$waittime){
            //睡眠1ms
            usleep(1000);
            //参数 nx 代表key不存在才操作, ex 缓存有效时间
            $ok = $this->redis->set($key, $this->lock, array('nx', 'ex' => $overtime));
            if ($ok) {
                return $this->lock;
            }
        }
        return false;

    }

    /**
     * @param $key 加锁的key
     * @return bool
     */
    public function unlock($key){
        if (!empty($this->lock)){
            $lock=$this->redis->get($key);
            if (!empty($lock)&&$lock==$this->lock){
               return $this->redis->del($key);
            }
        }
        return false;
    }

}

PS:Redis 可以使用lua 脚本实现多个命令的原子性,详情自行搜索

二:乐观锁

特性:
1:不锁定资源
2:在提交时才检验数据是否被修改

乐观锁实现伪代码

public function lgLock($key){
		//获取原始数据
        $data=$redis->get($key);
        //添加观测
        $redis->watch($key);
        //事务
        $redis->multi();
        //do something

        //简单粗暴,原始数据没有被修改直接更新,修改了直接失败
       return $redis->exec();

    }

redis乐观锁使用注意看这里
Redis 乐观锁watch,multi 顺序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值