单机Redis实现分布式锁

1 篇文章 0 订阅

最近有个项目用到了锁,直接想到了redis,在网上查看了一下案列,总感觉不是特别符合需求,索性自己写了一个。

供大家参考,有问题请留意,共同学习提高。

不多说,直接上代码:

 

<?php
/**
 * Class redis_lock
 *
 * 单机redis 分布式锁
 */

class redis_lock
{
    public $redis;

    public function __construct()    //连接Redis服务器
    {
        $this->redis = new \redis();
        $this->redis->connect('127.0.0.1', 6379);
//      $this->redis->auth('123456');
//      $this->redis->select(12);
    }

    /**
     * 单台Redis设置锁
     *
     * @param string $key
     * @param int $expire
     * @return bool
     */
    public function setLock($key, $expire = 10)
    {
        $res = $this->check_key($key);
        if (!$res) {
            return false;
        }
        $res = $this->check_expire($expire);
        if (!$res) {
            return false;
        }
        $res = $this->redis->set('Redis:Lock:' . $key, time() + $expire, ['nx', 'ex' => $expire]);
        if (!$res) {
            return false;
        }
        return true;
    }

    /**
     * 校验有效期
     *
     * @param mixed $expire
     * @return int
     */
    public function check_expire($expire)
    {
        if (!is_numeric($expire)) {
            return false;
        }
        return true;
    }

    /**
     * 校验$key
     *
     * @param mixed $key
     * @return bool
     */
    public function check_key($key)
    {
        if (!is_string($key) && !is_int($key)) {
            return false;
        }
        //允许数字、英文字符、下划线、英文冒号
        preg_match('/^[\w\:]*+$/', $key, $p_key);
        if (!isset($p_key[0]) || $p_key[0] != $key) {
            return false;
        }
        return true;
    }

    /**
     * 单台Redis设备锁,如果不能进入将等待
     *
     * @param string $key
     * @param int $expire
     * @param int $wait_seconds
     * @return bool
     */
    public function setLockAndWait($key, $expire = 10, $wait_seconds = 10)
    {
        /*如果是webserver,并且session服务器是文件或者memcache,最好加上这一行
        也可以用session_commit(),解除session锁。如果session服务器是redis,就不用了*/
        session_write_close();
        $time = time();
        $wait_time = $time + $wait_seconds;
        while (true) {
            $res = $this->setLock($key, $expire);
            if ($res) {
                return $res;
            }
            if ($time >= $wait_time) {
                return false;
            }
            usleep(500);    //等待微妙数
        }
    }

    /**
     * 单台Redis删除锁
     *
     * @param string $key
     * @return bool
     */
    public function delLock($key)
    {
        $res = $this->redis->del($key);
        if ($res === false) {
            return false;
        }
        return true;
    }
}

$redis = new redis_lock();
$res = $redis->setLock('111');
$redis->delLock('111');
var_dump($res);
exit;
?>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值