Redisson分布式锁
模板代码了,属于是,可以直接拿来用。
最近在重构一个10年前的系统,当年分布式锁用setNx手搓的,现在直接用Redisson,看门狗机制省了在锁失效时间上纠结。
RLock lock = redissonClient.getLock("lock-" + key);
boolean locked = false;
try {
locked = lock.tryLock(3, TimeUnit.SECONDS); //获取锁,wait 3秒超时,如果这3秒内被中断则抛InterruptedException
if (locked) {
//业务逻辑
return RetCode.OK;
} else {
return RetCode.LOCKFAILD;
}
}catch (InterruptedException e){ //抛这个异常意味着,等待获取锁过程中,没到超时时间之前被中断等待。
// 抛这个异常后,线程中断标志被清除
Thread.currentThread().interrupt(); //恢复中断标志
return RetCode.LOCKFAILD;
}finally {
if(locked)
lock.unlock();
}
Redisson配置:
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host:localhost}")
private String redisHost;
@Value("${spring.redis.port:6379}")
private int redisPort;
@Value("${spring.redis.password:123456}")
private String password;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://" + redisHost + ":" + redisPort)
.setPassword(password)
.setConnectionPoolSize(64)
.setConnectionMinimumIdleSize(10);
config.setLockWatchdogTimeout(30000L); //看门狗,每隔watchdogTimeout/3(如果线程还活着)进行续期30s
return Redisson.create(config);
}
}
时间节点:
拿到锁 → 设过期 30s
↓
10s 后检查线程是否还存活
↓
是 → 再续 30s → 10s 后再检查 → 无限循环
↓
否 → 停止续期,等 30s 后 Redis 自动删 key
↓
业务调了 unlock → 立即停止续期,删 key
注意:tryLock(3, 10, TimeUnit.SECONDS) 一旦指定了 leaseTime(那个 10 秒),Redisson不会启动看门狗,锁到点自动释放。
浙公网安备 33010602011771号