Spring Boot 中 Redis 分布式锁的正确使用姿势,我后悔没早知道
Spring Boot 中 Redis 分布式锁的正确使用姿势我后悔没早知道上个月项目里一个定时任务重复执行了两次导致数据被重复处理查了很久才发现是分布式锁失效了。当时我用的是 Redis SETNX 命令自认为写得没问题结果在并发场景下完全不行。这篇文章把踩过的坑和正确的做法分享出来希望你们别再重蹈覆辙。一、为什么你的分布式锁总失效先说说我踩的第一个坑。当时我自信满满地写了这样的代码publicBooleantryLock(StringlockKey,StringrequestId){BooleanresultredisTemplate.opsForValue().setIfAbsent(lockKey,requestId,10,TimeUnit.SECONDS);returnresult;}看起来挺完美对吧设置了 10 秒过期时间防止锁死。但是问题来了问题场景线程 A 获取锁后开始执行任务执行到一半时业务逻辑耗时超过了 10 秒锁自动过期释放。此时线程 B 正好进来也成功获取了锁。这样 A 和 B 同时在执行同一任务数据就被重复处理了。根本原因我没有正确理解 Redis 分布式锁的看门狗机制。锁的过期时间应该由业务执行时间动态决定而不是写死一个固定值。二、Redis 分布式锁的核心原理想用好分布式锁先得搞懂它的核心原理。Redis 分布式锁本质上是利用 SETNXSET if Not eXists命令的原子性// 伪代码获取锁if(redis.setnx(lockKey,requestId)1){// 获取成功设置过期时间redis.expire(lockKey,30);try{// 业务逻辑}finally{// 释放锁if(requestId.equals(redis.get(lockKey))){redis.del(lockKey);}}}但这段代码有三个致命问题问题1SETNX 和 EXPIRE 不是原子操作如果程序在 SETNX 成功后、EXPIRE 执行前崩溃锁就永远不会过期。问题2释放锁时没有验证价值如果线程 A 的锁过期了线程 B 获取了新锁此时线程 A 执行完毕去释放锁会把线程 B 的锁给释放掉。问题3无法自动续期业务执行时间超过锁过期时间锁自动失效其他线程可以进来搞破坏。三、Redisson 框架的正确打开方式说了这么多坑该上正确的解决方案了。Redisson 是 Java 中最成熟的 Redis 客户端之一它帮我们封装好了分布式锁的所有细节。1. 引入依赖dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.24.3/version/dependency2. 配置 Redisson 客户端ConfigurationpublicclassRedissonConfig{Value(${spring.data.redis.host})privateStringhost;Value(${spring.data.redis.port})privateStringport;BeanpublicRedissonClientredissonClient(){ConfigconfignewConfig();Stringaddressredis://host:port;config.useSingleServer().setAddress(address).setPassword(yourpassword)// 如果有密码.setConnectionPoolSize(64).setConnectionMinimumIdleSize(10);returnRedisson.create(config);}}3. 使用分布式锁ServicepublicclassOrderService{AutowiredprivateRedissonClientredissonClient;publicvoidcreateOrder(Orderorder){StringlockKeyorder:lock:order.getProductId();RLocklockredissonClient.getLock(lockKey);try{// 等待锁超时时间 10 秒自动解锁时间 30 秒// watchDog 会自动续期lock.lock(30,TimeUnit.SECONDS);// 业务逻辑检查库存、创建订单、扣减库存checkStock(order);saveOrder(order);deductStock(order);}catch(Exceptione){log.error(Order creation failed,e);thrownewRuntimeException(创建订单失败,e);}finally{// 释放锁if(lock.isHeldByCurrentThread()){lock.unlock();}}}}这样写有几个好处自动续期Redisson 内置看门狗机制默认每 10 秒检查一次如果业务还在执行自动续期 30 秒原子操作获取锁和设置过期时间是原子执行的可重入同一个线程可以多次获取同一把锁四、常见坑点与最佳实践坑点1锁的 key 设计不合理错误做法所有业务都用同一个 keylock正确做法按业务维度设计 key例如// 订单业务StringlockKeylock:order:orderId;// 库存业务StringlockKeylock:stock:productId;// 分布式环境下用 UUID 线程 ID 确保唯一性StringrequestIdUUID.randomUUID().toString():Thread.currentThread().getId();坑点2释放锁时没有验证 owner错误做法// 直接删除不检查是谁的锁redisTemplate.delete(lockKey);正确做法// Redisson 自动处理了这个逻辑// 释放锁时会验证是否是当前线程持有的锁lock.unlock();如果用原生 Redis要用 Lua 脚本保证原子性Stringscriptif redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end;redisTemplate.execute(newDefaultRedisScript(script,Long.class),Collections.singletonList(lockKey),requestId);坑点3没有处理获取锁失败的情况错误做法获取不到锁就直接报错正确做法根据业务场景选择等待策略// 策略1等待并重试booleanacquiredlock.tryLock(10,30,TimeUnit.SECONDS);if(acquired){try{// 业务逻辑}finally{lock.unlock();}}else{// 获取锁失败执行降级逻辑log.warn(Failed to acquire lock, executing fallback);executeFallback();}// 策略2立即返回不阻塞if(lock.tryLock()){try{// 业务逻辑}finally{lock.unlock();}}else{// 直接返回结果或提示用户returnResult.fail(系统繁忙请稍后重试);}坑点4集群环境下锁失效如果 Redis 是主从架构主节点宕机时可能导致锁丢失。建议使用 RedLock 算法或 Redis Cluster// Redisson RedLock 配置RLocklock1redissonClient1.getLock(lockKey);RLocklock2redissonClient2.getLock(lockKey);RLocklock3redissonClient3.getLock(lockKey);RedissonRedLockredLocknewRedissonRedLock(lock1,lock2,lock3);redLock.lock();try{// 业务逻辑}finally{redLock.unlock();}写在最后分布式锁是微服务架构中的必备技能用错了轻则数据重复重则资金损失。我在项目里血的教训总结下来就三点用成熟的框架别自己造轮子Redisson 已经处理了大部分边界情况注意锁的粒度key 设计要足够细避免影响并发性能做好失败降级获取不到锁时要有兜底方案别把所有请求都堵死希望这篇文章能帮你们少踩坑。如果觉得有用点个赞再走相关推荐Redisson 官方文档Redis 分布式锁详解

相关新闻

Seedance 2.0动态光影重绘为何越升级越卡?——揭秘2.0.3版本中被忽略的Uniform Buffer对齐缺陷与修复补丁

Seedance 2.0动态光影重绘为何越升级越卡?——揭秘2.0.3版本中被忽略的Uniform Buffer对齐缺陷与修复补丁

第一章:Seedance 2.0动态光影重绘算法性能退化现象总览Seedance 2.0 引入的动态光影重绘算法(Dynamic Light Redraw Algorithm, DLRA)在高帧率渲染场景下表现出显著的性能退化趋势,尤其在多光源交叠、半透明材质频繁更新及视口快速…

2026/7/3 0:10:12 阅读更多 →
MedGemma医学影像AI助手应用场景:AI辅助生成医学影像学实习考核试题

MedGemma医学影像AI助手应用场景:AI辅助生成医学影像学实习考核试题

MedGemma医学影像AI助手应用场景:AI辅助生成医学影像学实习考核试题 1. 引言:当医学教学遇上AI助手 想象一下,你是一位医学影像学的带教老师。明天要给实习生们安排一次读片考核,你需要从海量的影像库中筛选合适的病例&#xff…

2026/5/17 5:18:21 阅读更多 →
低查重“杀手级”利器!AI教材编写工具助你高效产出靠谱教材!

低查重“杀手级”利器!AI教材编写工具助你高效产出靠谱教材!

整理教材知识点难题与 AI 教材写作工具解决方案 整理教材的知识点简直是一项“细致活”,特别难在于如何找到平衡和衔接的最好方式!我们总是面临两种困扰:一方面担心会漏掉重要的核心知识;另一方面则是在难度把控上显得捉襟见肘—…

2026/5/17 5:18:21 阅读更多 →

最新新闻

ASM330LHH与PIC18F4525实现低成本运动跟踪方案

ASM330LHH与PIC18F4525实现低成本运动跟踪方案

1. 项目背景与核心组件解析运动跟踪技术正在从工业级应用向消费电子领域快速渗透,而ASM330LHH与PIC18F4525的组合为开发者提供了一个高性价比的解决方案。ASM330LHH是STMicroelectronics推出的6轴MEMS惯性测量单元(IMU),集成了3轴数字加速度计和3轴数字陀…

2026/7/3 0:10:00 阅读更多 →
13DOF传感器与PIC32MZ实现厘米级自主导航方案

13DOF传感器与PIC32MZ实现厘米级自主导航方案

1. 项目背景与核心需求在自主移动机器人、无人机和工业自动化领域,精确定位与导航一直是核心技术挑战。传统GPS在室内环境完全失效,而UWB(超宽带)技术虽然能提供10-30cm的定位精度,但对于需要厘米级精度的应用场景&…

2026/7/3 0:10:00 阅读更多 →
AD74413R与PIC18F65K40的高精度工业数据采集方案

AD74413R与PIC18F65K40的高精度工业数据采集方案

1. 项目概述:AD74413R与PIC18F65K40的协同工作在工业自动化和精密测量领域,同时实现高精度模数转换(ADC)和数模转换(DAC)功能是许多复杂系统的核心需求。AD74413R作为一款四通道可配置模拟输入/输出器件,与PIC18F65K40微控制器的组合&#xf…

2026/7/3 0:05:59 阅读更多 →
华为防火墙双通道远程管理实战:Web与SSH配置详解

华为防火墙双通道远程管理实战:Web与SSH配置详解

1. 项目概述:为什么需要双通道远程管理防火墙?在任何一个稍具规模的企业网络里,防火墙都是那个默默守护在边界的关键角色。作为网络工程师,我们不可能每次都跑到机房,插上console线去配置它。远程管理能力,…

2026/7/3 0:03:59 阅读更多 →
Nginx防御TLS重协商攻击实战:从原理到配置与监控

Nginx防御TLS重协商攻击实战:从原理到配置与监控

1. 项目概述:为什么TLS重协商攻击至今仍需警惕十多年前的CVE-2011-1473,一个关于TLS/SSL协议重协商机制的漏洞,现在提起来还有必要吗?很多运维和开发朋友可能会觉得,这都老掉牙了,现代服务器和客户端不都默…

2026/7/3 0:03:59 阅读更多 →
告别复杂制图软件,okbiye AI 科研绘图线上一键生成学术标准图表

告别复杂制图软件,okbiye AI 科研绘图线上一键生成学术标准图表

okbiye-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/科研绘图科研绘图 - Okbiye智能写作https://www.okbiye.com/drawing 一、科研绘图痛点直击:传统制图模式拖慢整体科研进度 对于本科生、硕博生以及一线科研从业者来说,学术图表是论文…

2026/7/2 23:57:57 阅读更多 →

日新闻

Nginx防御TLS重协商攻击实战:从原理到配置与监控

Nginx防御TLS重协商攻击实战:从原理到配置与监控

1. 项目概述:为什么TLS重协商攻击至今仍需警惕十多年前的CVE-2011-1473,一个关于TLS/SSL协议重协商机制的漏洞,现在提起来还有必要吗?很多运维和开发朋友可能会觉得,这都老掉牙了,现代服务器和客户端不都默…

2026/7/3 0:03:59 阅读更多 →
华为防火墙双通道远程管理实战:Web与SSH配置详解

华为防火墙双通道远程管理实战:Web与SSH配置详解

1. 项目概述:为什么需要双通道远程管理防火墙?在任何一个稍具规模的企业网络里,防火墙都是那个默默守护在边界的关键角色。作为网络工程师,我们不可能每次都跑到机房,插上console线去配置它。远程管理能力,…

2026/7/3 0:03:59 阅读更多 →
AD74413R与PIC18F65K40的高精度工业数据采集方案

AD74413R与PIC18F65K40的高精度工业数据采集方案

1. 项目概述:AD74413R与PIC18F65K40的协同工作在工业自动化和精密测量领域,同时实现高精度模数转换(ADC)和数模转换(DAC)功能是许多复杂系统的核心需求。AD74413R作为一款四通道可配置模拟输入/输出器件,与PIC18F65K40微控制器的组合&#xf…

2026/7/3 0:05:59 阅读更多 →

周新闻

月新闻