Redis 分布式锁学习笔记:setIfAbsent 和 Redisson

写在前面

分布式锁是我学习库存扣减、重复提交和定时任务时接触到的内容。这篇只记录基础理解。

setIfAbsent

Redis 实现锁的基础思路是:只有第一个请求能写入某个 key。

1
2
Boolean success = redisTemplate.opsForValue()
.setIfAbsent("lock:order:" + orderId, requestId, 10, TimeUnit.SECONDS);

要注意:

  • 锁要有过期时间
  • value 最好是唯一标识
  • 释放锁时要判断是不是自己的锁

释放锁

释放锁不能简单删除 key,最好用 Lua 保证判断和删除的原子性。

1
2
3
4
5
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end

Redisson

真实项目里常用 Redisson,因为它封装了很多细节。

1
2
3
4
5
6
7
8
9
10
11
12
RLock lock = redissonClient.getLock("lock:order:" + orderId);
try {
boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
if (!locked) {
return;
}
// business
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}

小结

分布式锁不是万能方案。很多场景还需要数据库唯一索引、幂等 token、状态机等方式兜底。


Redis 分布式锁学习笔记:setIfAbsent 和 Redisson
https://zxyblog.top/2024/10/18/Redis分布式锁学习笔记-setIfAbsent和Redisson/
作者
zxy
发布于
2024年10月18日
许可协议