分布式锁死锁问题

现象 接口偶发卡死,请求一直等待不返回。 排查后发现某个 key 长时间存在,业务线程始终获取不到锁。 原始实现 使用 setnx 实现分布式锁: Boolean lock = redisTemplate.opsForValue() .setIfAbsent("order_lock", "1"); if (Boolean.TRUE.equals(lock)) { try { // 执行业务 } finally { redisTemplate.delete("order_lock"); } } 问题原因 当服务在执行过程中异常退出(例如进程重启), finally 块没有执行,锁未删除。 由于没有设置过期时间,key 会一直存在。 后续请求全部获取锁失败,形成类似“死锁”的情况。 调整方案 增加过期时间: Boolean lock = redisTemplate.opsForValue() .setIfAbsent("order_lock", "1", 30, TimeUnit.SECONDS); 避免锁永久存在。 进一步问题 如果业务执行超过 30 秒, 锁提前过期,其他线程可能获取锁,造成并发执行。 改进方式 使用唯一标识作为 value: String requestId = UUID.randomUUID().toString(); Boolean lock = redisTemplate.opsForValue() .setIfAbsent("order_lock", requestId, 30, TimeUnit.SECONDS); 释放锁时校验 value: ...

May 21, 2024 · 1 min · Faithlv