PHPRedis 和锁定

问题描述 投票:0回答:3

我得到了以下两个用于锁定 Redis 键的函数。我正在尝试使用 Redis 阻止并发执行一段代码。所以我所做的是以这样的方式使用以下函数,以防止不同线程执行相同的代码。

lockRedisKey("ABC");
CODE THAT I DON'T WANT TO RUN CONCURRENTLY!
unlockRedisKey("ABC");

不幸的是,它似乎不起作用并在 lockRedisKey() 处导致无限循环,直到达到 exit_time。有什么问题吗?

  static public function lockRedisKey($key, $value = "true") {

        $redis = RedisClient::getInstance();

        $time = microtime(true);
        $exit_time = $time + 10;
        $sleep = 10000;

        do {

            // Lock Redis with PX and NX

            $lock = $redis->setnx("lock:" . $key, $value);

            if ($lock == 1) {
                $redis->expire("lock:" . $key, "10");
                return true;
            }

            usleep($sleep);

        } while (microtime(true) < $exit_time);

        return false;

    }

    static public function unlockRedisKey($key) {

        $redis = RedisClient::getInstance();

        $redis->del("lock:" . $key);

    }

我知道我可能会遇到死锁,所以我决定使用事务,但我仍然面临这个问题。


    static public function lockRedisKey($key, $value = "true") {

        $redis = RedisClient::getInstance();

        $time = microtime(true);
        $exit_time = $time + 10;
        $sleep = 10000;

        do {

            // Lock Redis with PX and NX

            $redis->multi();
            $redis->set('lock:' . $key, $value, array('nx', 'ex' => 10));
            $ret = $redis->exec();

            if ($ret[0] == true) {
                return true;
            }

            usleep($sleep);

        } while (microtime(true) < $exit_time);

        return false;

    }

    static public function unlockRedisKey($key) {

        $redis = RedisClient::getInstance();

        $redis->multi();
        $redis->del("lock:" . $key);
        $redis->exec();

    }

php redis locking
3个回答
0
投票

锁定工作正常。这只是崩溃和导致锁不被释放的锁定之间的代码:-)


0
投票

你的'exit_time'太小了。 我认为'$exit_time = $time + 10;'的意思就是10秒后关机。 但是,设置的时间是微时间。

也许你可以替换'$exit_time = $time + 10;'使用“$exit_time = $time + 100000;”。 由谷歌翻译撰写


-1
投票

首先,PHP 不像 JS f.e. 那样是异步脚本语言。您无法控制脚本执行顺序,因此这意味着您无法以并发方式运行以下

lockRedisKey()
调用的代码。

我假设您不完全理解 usleep 函数实际上在做什么,它只是 delay 进程而不是 postpone 它,所以它只是阻止进程

$sleep
时间,然后继续执行脚本。所以你不是通过调用你的脚本来执行并发写入。

© www.soinside.com 2019 - 2024. All rights reserved.