Predis使用事务执行两条命令,但其中一条失败
P粉030479054
P粉030479054 2023-09-13 17:55:41
0
1
377

描述错误

我使用redis列表来做一个限制器,它大多数时候都按预期工作,但最近我发现有一些键没有过期时间。理想情况下,我将值“rpush”到列表中,并在一个中设置过期时间交易,并且在交易开始之前我也使用“watch”。

重现

我本地环境没有复现这个bug,即使我使用jmeter批量请求相关api,比如1秒500个请求

版本:

预测:v2.1.2 PHP 7.4 Redis服务器5.0.10

代码示例

$redisClient->watch($key);
$current = $redisClient->llen($key);

// Transaction start
$tx = $redisClient->transaction();
if ($current >= $limitNum) {
    $redisClient->unwatch();
    return false;
} else {
  
    if ($redisClient->exists($key)) {
        $tx->rpush($key, $now);

        try {
             $replies = $tx->execute();
             return true;
        } catch (\Exception $e) {
            return false;
        }
    } else {
        // Using transaction to let rpush and expire to be an atomic operation
        $tx->rpush($key, $now);
        $tx->expire($key, $expiryTime);

        try {
             $replies = $tx->execute();
             return true;
        } catch (\Exception $e) {
            return false;
        }
    }
}

其他

这是我的本地 Redis 服务器中的预期操作

Redis 事务是原子的。原子意味着要么处理所有命令,要么不处理任何命令。因此,在我的情况下,一把钥匙应该有有效期。

P粉030479054
P粉030479054

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!