springboot redisson 分布式锁切面入门与实战
Spring Boot3 Redisson 项目地址
https://gitee.com/supervol/loong-springboot-study
(记得给个start,感谢)
分布式锁介绍
在分布式系统中,多个服务实例(节点)可能同时操作共享资源(如数据库记录、缓存数据等),此时本地锁(如synchronized
、ReentrantLock
)无法跨节点生效,会导致并发安全问题(如超卖、数据不一致)。分布式锁正是为解决这类问题而生 —— 它是一种跨节点的互斥机制,确保同一时间只有一个节点能操作共享资源。
实现分布式锁需满足以下关键特性:
- 互斥性:同一时间只能有一个节点持有锁。
- 安全性:避免死锁(如锁超时自动释放),防止误释放他人的锁。
- 可用性:锁服务需高可用,避免单点故障。
- 重入性:同一节点的同一线程可重复获取已持有的锁(可选,视场景而定)。
- 公平性:按请求顺序获取锁(可选)。
Redisson 分布式锁简介
Redisson 是基于 Redis 的 Java 客户端,提供了丰富的分布式数据结构(包括分布式锁),其实现的分布式锁具有以下核心特性:
- 可重入性:同一线程可多次获取同一把锁,避免自死锁
- 自动续期:通过 "看门狗" 机制,在业务未完成时自动延长锁的过期时间,防止锁提前释放
- 公平 / 非公平锁:支持公平锁(按请求顺序获取)和非公平锁(默认)
- 红锁(RedLock):针对 Redis 集群,通过多个实例加锁提高可靠性
- 自动释放:支持设置过期时间,避免死锁
Redisson 分布式锁切面示例
请参考项目地址中 springboot-aop/springboot-redisson-lock 模块代码。
注意事项
- 锁的命名规范:锁名需唯一标识共享资源(如
业务:资源类型:唯一ID
),避免不同业务共用同一把锁。 - 释放锁的正确性:必须在
finally
中释放锁,且释放前需通过isHeldByCurrentThread()
判断是否持有锁,避免释放其他线程的锁。 - 过期时间设置:
- 若使用
lock()
(无过期时间),依赖看门狗自动续期(默认 30 秒,每 10 秒续期一次),适合业务耗时不确定的场景。 - 若使用
lock(leaseTime, unit)
,需确保leaseTime
大于业务最大耗时,否则锁会提前释放。
- 若使用
- 红锁(RedLock):在 Redis 集群环境(多主节点)中,可使用红锁提高可靠性(需操作多个独立 Redis 实例):
RLock lock1 = redissonClient1.getLock(lockKey); RLock lock2 = redissonClient2.getLock(lockKey); RLock lock3 = redissonClient3.getLock(lockKey);RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3); redLock.lock(10, TimeUnit.SECONDS); // 红锁加锁
- 性能考量:分布式锁会引入网络开销,避免过度使用;非核心业务可考虑最终一致性方案。
- 异常处理:切面中已通过
finally
确保锁释放,但业务方法抛出异常时需自行处理(如事务回滚)。
总结
通过 AOP 切面 + 自定义注解,Redisson 分布式锁的使用变得极为简洁:只需在方法上添加注解,即可实现分布式并发控制。这种方式既减少了重复代码,又统一了锁的管理逻辑,非常适合在 Spring Boot 3 项目中大规模使用。额外注意数据库事务需要特殊处理。