Redisson加锁问题

先看案例

@GetMapping("sayHi/{word}")
public String sayHi(@PathVariable("word") String word) {
    String lockKey = "spring2025004_" + word;
    RLock lock = redissonClient.getLock(lockKey);
    String result = "";
    try {
        log.info("lockKey:{}", lockKey);
        boolean lockResult = lock.tryLock(3, 120, TimeUnit.SECONDS);
        if (lockResult) {
            TimeUnit.SECONDS.sleep(60);
            result = word;
        }
    } catch (InterruptedException e) {
        log.error("demo error", e);
    } finally {
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
    return result;
}

大致逻辑是:

demo尝试3s内获取锁,取不到直接返回

获取到以后执行业务逻辑,逻辑超时的话会在120s后释放锁

没有超时则最终会主动释放锁

问题复现

有一次发现一个问题,有一个服务的释放时间设置成10min,执行时间可能比较久,然后SIT环境业务逻辑执行过程中,机器出现重启(后面发现流水线有人发包了),会发现只能等10min后才能执行这个服务,阻塞测试了。

在使用Redisson加分布式锁的时候,通常会使用tryLock方法,这个方法有多个重载

  • boolean tryLock();

  • boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

  • boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException;

第一个无参的是尝试立刻获取锁

第二个通过等待时间尝试获取锁

第三个通过等待时间尝试获取锁,然后指定过期时间,Redis自己的看门狗机制不会触发

也就是说如果手动设置了释放时间的话,看门狗不会去主动清理这个锁

因此在业务逻辑比较耗时的情况下,SE给出的建议是最好不要设置释放时间(存疑),或者把锁的粒度控制更细一点

但是我觉得如果不设置的话,可能存在一些异步处理还在执行,后续锁被看门狗清理掉又会出现新的异步处理导致数据冲突

posted @ 2025-05-22 23:07  一只盐桔鸡  阅读(14)  评论(0)    收藏  举报