You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis异步锁获取卡住问题排查:代码是否存在语法错误?

Redis异步锁无法通过acquire步骤的问题分析

你的代码没有语法错误,但存在导致锁阻塞的逻辑缺陷,同时有几个排查方向:

核心问题:未正确处理异常场景下的锁释放

在update函数中,当int(k) < 0触发ValueError时,await lock.release()不会被执行,导致锁被永久持有,后续所有任务都会阻塞在lock.acquire()步骤。

修复方案:使用async with自动管理锁

async with上下文管理器会在代码块结束(包括异常抛出时)自动释放锁,彻底避免锁泄漏问题,修改后的代码如下:

import redis.asyncio as redis
import tqdm
import asyncio

# 建议显式指定Redis连接参数,避免环境默认值差异
r = redis.Redis(host="localhost", port=6379, decode_responses=True)


async def update():
    # 用async with自动处理锁的获取与释放
    async with r.lock("lock"):
        k = await r.get("key")
        if int(k) < 0:
            raise ValueError(f"Value {k} is negative")
        await r.setex("key", 3600, -1)
        await asyncio.sleep(0.5)
        await r.setex("key", 3600, 1)


async def main():
    total = 100
    chunksize = 10
    await r.setex("key", 3600, 1)
    aws = [update() for _ in range(total)]
    with tqdm.tqdm(total=total) as pbar:
        for idx in range(0, total, chunksize):
            end = min(idx + chunksize, total)
            chunk = aws[idx:end]
            await asyncio.gather(*chunk)
            pbar.update(end - idx)
    

if __name__ == "__main__":
    asyncio.run(main())

其他排查方向

  • Redis连接验证:确认Redis服务正常运行,且代码中的连接参数(host、port、密码等)与实际环境匹配,避免因连接失败导致的隐性阻塞。
  • 残留锁清理:如果之前的异常运行导致锁残留,可以通过Redis客户端执行DEL lock手动删除锁键,再重新测试。

内容的提问来源于stack exchange,提问作者monopoly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:23:09