实际生产开发到底怎么用锁?单体本地锁/数据库锁/Redis分布式锁 真实场景

news2026/4/28 3:37:34
文章目录前言别再瞎加锁生产用锁只看「场景部署环境」一、第一种锁Java单体本地锁synchronized\Atomic原子类1.1 精准适用生产场景只有这种情况才用多一概不碰1.2 真实生产业务案例1.3 ❌ 错误写法不加锁并发必计数错乱1.4 ✅ 生产正确写法1synchronized本地锁新手简单首选零学习成本1.5 ✅ 生产正确写法2AtomicLong原子类性能更好计数专用生产推荐1.6 实操核心答疑单体计数场景直接用Redis不加锁代替Java本地锁可以吗二、第二种锁数据库锁悲观锁for update乐观锁版本号生产核心账务核心2.1 数据库锁生产四大核心划分维度必懂锁生效与否全靠这个维度一按并发控制策略划分开发日常最常用核心设计思想层面维度二按锁定粒度划分锁影响范围决定并发性能高低维度三按读写模式划分MySQL InnoDB底层真实锁实现锁生效底层核心维度四按作用层级划分区分谁管锁、谁写代码锁权责核心2.2 精准适用生产场景核心账务必用不分单体集群2.3 真实生产业务案例2.4 ❌ 错误写法不加锁集群必超卖锁维度不配置直接翻车2.5 ✅ 生产写法1数据库悲观锁 for update强一致首选底层行级排他锁兜底2.6 ✅ 生产写法2数据库乐观锁版本号机制应用层代码锁高性能优选2.7 数据库锁核心实操三连答疑生产必懂规避锁失效坑答疑1数据库加锁是代码加SQL还是数据库提前配置锁谁管控答疑2selectStockForUpdate是框架自带方法答疑3悲观锁、乐观锁是MySQL自动处理还是代码处理三、第三种锁Redis分布式锁SpringCloud微服务集群高并发生产标配3.1 什么是Redis分布式锁核心本质必懂3.2 Redis分布式锁常见类型按生产能力演进按需选用3.3 精准适用生产场景\与数据库锁核心选型对比再也不选错3.4 核心实操答疑Redis锁是原生自带改数据库还是改Redis配置3.5 Java代码两种实现方式手写懂原理生产只用Redisson3.5.1 手写极简版Redis锁仅学习理解原理生产绝对禁止上线3.5.2 生产标准唯一写法Redisson分布式锁线上直接复制上线3.6 生产Redis分布式锁避坑指南\最佳实践线上必看杜绝故障3.7 架构师终极总结四、生产终极锁选型对照表新手直接查表永不选错五、老开发最终一句话总结牢记不踩锁所有坑前言别再瞎加锁生产用锁只看「场景部署环境」很多新手学完并发、学完各种锁概念依然不会写代码。核心通病就一个背了一堆乐观锁、悲观锁、死锁八股到了实际开发不知道什么时候该加锁、该加哪种锁。我做了多年Java后端从单体SpringBoot做到SpringCloud微服务集群线上从没乱加过锁也从没出过并发数据错乱、超卖、重复扣款事故。今天不讲晦涩底层原理、不深挖AQS、不讲锁升级源码只讲生产开发唯一有用的核心事什么样的业务场景、什么样的服务器部署环境必须用哪种锁直接匹配场景、附上错误翻车代码、生产可直接上线可用代码。看完这篇你就彻底搞懂所有生产锁核心问题✅ 普通简单CRUD业务为啥一辈子不用加任何锁✅ 单体项目内存简单计数、本地监控用什么锁最合适✅ 电商下单扣库存、余额扣款防超卖核心业务用什么锁兜底✅ 微服务集群秒杀、分布式定时任务防重复执行用什么锁最优先记住生产终极锁选型口诀全篇围绕这个核心落地单实例、内存临时计数 → 用Java本地锁集群核心账务扣库存 → 用数据库锁微服务集群高并发、分布式任务 → 用Redis分布式锁。一、第一种锁Java单体本地锁synchronizedAtomic原子类1.1 精准适用生产场景只有这种情况才用多一概不碰✅ 同时满足两个条件无脑直接用本地锁性价比最高项目是单体SpringBoot单实例部署无集群、无多台服务器负载均衡、无微服务拆分业务仅为内存临时统计、本地接口热度限流、内存瞬时计数器不跨服务调用、不涉及核心资金账务、不做库存扣减、无需持久化存储。❌ 绝对禁止使用场景集群分布式环境、微服务跨服务业务、下单扣款核心交易、秒杀库存扣减、分布式定时任务防重。本地锁仅作用于单JVM内存集群多实例下完全失效并发数据错乱必翻车。1.2 真实生产业务案例开发单体项目接口访问次数实时统计功能无需频繁读写数据库仅在内存累计接口瞬时访问量用于后台简单监控接口调用热度、排查接口异常波动无需长久持久化、无需跨实例共享数据。1.3 ❌ 错误写法不加锁并发必计数错乱多用户多线程同时访问接口普通成员变量自增存在线程安全问题计数互相覆盖丢失数据统计结果永远不准确监控功能直接失效。RestControllerRequestMapping(/monitor)publicclassMonitorController{// 成员变量共享多线程并发修改必出现数据覆盖错乱privateintvisitCount0;GetMapping(/visit)publicStringvisit(){// 线程不安全自增操作高并发下必丢计数数据visitCount;return接口当前累计访问次数visitCount;}}1.4 ✅ 生产正确写法1synchronized本地锁新手简单首选零学习成本单实例环境下完美生效通过JVM层面保证同一时间只允许一个线程执行计数逻辑并发排队串行执行计数数据绝对准确代码改动极小、上手无门槛。RestControllerRequestMapping(/monitor)publicclassMonitorController{privateintvisitCount0;// 加本地锁单实例并发线程排队执行彻底解决计数错乱问题GetMapping(/visit)publicsynchronizedStringvisit(){visitCount;return【synchronized本地锁】累计访问次数visitCount;}}1.5 ✅ 生产正确写法2AtomicLong原子类性能更好计数专用生产推荐基于无锁CAS自旋操作实现线程安全无重量级锁阻塞开销比synchronized同步锁性能高出数倍是生产内存计数、本地轻度限流的首选方案。RestControllerRequestMapping(/monitor)publicclassMonitorController{// 原子类天然线程安全替代普通int变量无需手动加锁privatefinalAtomicLongvisitTotalnewAtomicLong(0);GetMapping(/visit/atomic)publicStringvisitAtomic(){// 原子自增方法高并发计数永不丢失、无数据覆盖longcurrentvisitTotal.incrementAndGet();return【Atomic原子类本地锁】累计访问次数current;}}1.6 实操核心答疑单体计数场景直接用Redis不加锁代替Java本地锁可以吗很多新手都会纠结单体项目做接口访问计数、本地临时统计不想用synchronized、Atomic本地锁直接把计数放Redis里不加任何锁能不能直接用生产标准答案语法能跑、并发安全但生产绝不推荐纯属杀鸡用牛刀。1、为啥Redis不加锁也能计数安全Redis核心底层是单线程模型执行核心读写命令所有increment、get、set等操作串行排队执行天然具备并发安全特性。单体项目计数直接用Redis自增命令increment多线程同时访问也不会出现计数覆盖、数据错乱不需要手动加任何锁。// Redis不加锁实现单体计数并发安全但生产不推荐使用RestControllerRequestMapping(/monitor)publicclassRedisCountController{AutowiredprivateStringRedisTemplateredisTemplate;privatestaticfinalStringCOUNT_KEYlocal:monitor:visit:count;GetMapping(/visit/redis)publicStringvisitRedis(){// Redis自增单线程串行执行天然安全无需手动加锁LongcountredisTemplate.opsForValue().increment(COUNT_KEY,1);return【Redis无锁计数】累计访问次数count;}}2、为啥生产单体计数不用Redis非要用Java本地锁性能差距巨大Atomic本地内存计数是纳秒级响应Redis计数需要额外网络IO、数据序列化、网络往返开销性能慢几十上百倍高频监控计数差距极其明显架构冗余没必要只是单体临时内存统计不需要数据持久化、不需要跨服务共享数据没必要额外依赖Redis中间件增加架构复杂度运维徒增风险Java本地锁不依赖任何第三方组件Redis一旦宕机、网络波动、集群超时计数监控功能直接失效徒增线上故障风险。生产最终选择单体纯本地临时计数、无需持久化场景优先用AtomicLong/Java本地锁只有计数需要跨服务共享、长久持久化归档才用Redis无锁计数。二、第二种锁数据库锁悲观锁for update乐观锁版本号生产核心账务核心原基础内容仅提供了数据库悲观锁、乐观锁实操代码缺少MySQL数据库锁核心底层划分维度、引擎适配规则、锁层级权责划分这也是很多开发加锁后依然出现锁失效、超卖、数据库死锁、性能卡顿的核心原因。下面先补充生产开发必须掌握的数据库锁四大核心划分维度打通原理和实操关联再衔接原有生产案例和落地代码做到懂原理、会写代码、不踩坑。2.1 数据库锁生产四大核心划分维度必懂锁生效与否全靠这个MySQL数据库锁不是单一形态生产使用、代码加锁、故障排查都要按四大维度精准区分不同维度组合决定锁的生效范围、性能高低、并发能力绝非简单只分悲观锁和乐观锁。维度一按并发控制策略划分开发日常最常用核心设计思想层面这是业务开发层面最常讨论的锁分类核心区别在于对待并发冲突的预判态度也是我们代码实操悲观锁、乐观锁的核心依据直接对应库存扣减、账务扣款业务选型。悲观锁默认认为并发一定会出现数据修改冲突提前提前加锁锁住资源其他线程/服务必须排队等待当前事务执行完毕释放锁后才能操作。核心追求数据绝对一致性牺牲部分并发性能适合核心账务、库存扣款不容出错的业务。乐观锁默认认为并发数据修改冲突概率极低不上锁不阻塞线程仅在数据更新时校验数据是否被其他线程修改过冲突则直接更新失败可代码重试处理。核心追求高并发高性能容忍少量冲突重试适合并发量大、冲突少、非极致强一致的业务。维度二按锁定粒度划分锁影响范围决定并发性能高低锁定粒度指加锁后锁住的数据库资源范围粒度越小并发性能越好粒度越大锁冲突越多、性能越差核心和MySQL存储引擎强绑定InnoDB和MyISAM引擎默认粒度完全不同。行锁InnoDB引擎默认支持仅锁住当前操作的单条数据行其他数据行不受影响并发互不干扰粒度最小、并发性能最好生产扣库存、单条账务修改必须用行锁表锁MyISAM引擎默认锁粒度加锁直接锁住整张数据表所有读写操作全部阻塞排队粒度最大、并发极差仅适合静态数据、极少修改的字典表核心业务绝对禁用页锁MySQL中间过渡锁粒度锁住数据库数据页多行数据性能和并发介于行锁和表锁之间生产开发几乎不用无需业务层面手动关注。维度三按读写模式划分MySQL InnoDB底层真实锁实现锁生效底层核心这是MySQL引擎底层实际运行的锁类型我们代码写的悲观锁、行锁底层都是基于这几类读写锁实现不懂这个就会出现明明加锁却锁失效、锁升级为表锁的隐形问题。共享锁S锁读锁多个线程可同时加共享锁、并行读数据互不阻塞但加了共享锁后任何线程都无法加排他锁修改数据保证读数据期间数据不被篡改排他锁X锁写锁也就是我们悲观锁for update底层用到的核心锁同一时间只允许一个线程加排他锁读写数据其他所有线程读写全部阻塞排队保证数据修改期间绝对独占意向锁IS/IX意向共享/意向排他锁InnoDB自动维护、无需代码手动加是表级辅助锁作用是快速判断数据表是否有行锁冲突避免全表遍历校验优化锁判断效率开发无需手动操作只需了解存在即可。维度四按作用层级划分区分谁管锁、谁写代码锁权责核心核心区分锁能力来自数据库引擎还是业务代码架构设计彻底搞懂锁是全自动生效还是需要程序员手动编码实现告别锁失效不知道原因的问题。数据库引擎锁锁的核心能力由MySQL底层引擎提供锁的加锁、释放、排队机制由数据库自动管控程序员只需代码触发即可。典型代表悲观锁for update数据库提供行锁、事务锁能力代码只需要开启事务、手写加锁SQL事务提交/回滚后数据库自动释放锁应用层锁代码/架构锁数据库仅作为数据存储“计算器”不提供任何锁机制所有锁校验、冲突判断、重试逻辑全部由业务代码手动实现。典型代表乐观锁版本号机制数据库只负责存储version版本字段加锁校验、冲突重试、版本更新全靠代码编写数据库不做任何自动锁管控。2.2 精准适用生产场景核心账务必用不分单体集群✅ 满足以下场景无脑用数据库锁兜底稳定性拉满项目集群部署、微服务SpringCloud多实例负载均衡环境本地锁完全失效核心资金账务业务电商下单扣商品库存、用户账户余额扣款、订单防重复创建、资金对账核算业务要求数据绝对强一致性零容忍超卖、重复扣款、数据错乱、账务不平事故。核心优势不管部署多少台服务器集群数据库锁全局唯一生效依托InnoDB引擎行级锁机制数据兜底稳定性拉满无需额外运维Redis等中间件核心账务生产首选兜底方案。2.3 真实生产业务案例电商平台下单扣商品库存业务服务集群多实例部署高并发下单场景下必须保证商品库存绝不超卖、扣减数据精准无误哪怕并发量不算极高核心账务也必须加数据库锁兜底防护。2.4 ❌ 错误写法不加锁集群必超卖锁维度不配置直接翻车多台服务实例同时查询库存、判断库存、执行扣减无任何锁管控并发逻辑直接绕过业务判断库存被扣成负数出现严重超卖、资损事故哪怕后续补数据也无法挽回线上影响。// 危险代码无锁扣库存集群环境必超卖生产严禁使用TransactionalpublicvoiddeductStock(LonggoodsId){// 多线程多实例同时查询拿到同一个库存数值并发判断全部绕过StockstockstockMapper.selectById(goodsId);if(stock.getStockNum()0){// 并发同时执行扣减数据互相覆盖库存直接扣成负数超卖stock.setStockNum(stock.getStockNum()-1);stockMapper.updateById(stock);}}2.5 ✅ 生产写法1数据库悲观锁 for update强一致首选底层行级排他锁兜底基于InnoDB引擎**行级排他锁X锁**实现查询库存时手动加for update悲观锁精准锁住当前商品单条数据行其他服务线程自动排队等待当前事务执行完毕提交后数据库引擎自动释放锁彻底杜绝超卖强一致业务首选。第一步Mapper自定义手写悲观锁查询SQL触发数据库引擎行锁框架无自带方法// 数据库悲观锁查询精准锁住当前数据行集群全局生效底层加行级排他锁Select(select * from stock where goods_id #{goodsId} for update)StockselectStockForUpdate(Param(goodsId)LonggoodsId);第二步Service业务扣减代码事务加持引擎自动锁管控ServicepublicclassStockService{AutowiredprivateStockMapperstockMapper;// 事务必须开启悲观锁生效完全依赖数据库事务事务结束自动释放排他锁Transactional(rollbackForException.class)publicvoiddeductStockPessimistic(LonggoodsId){// 悲观锁查询InnoDB引擎加行级排他锁其他线程排队阻塞StockstockstockMapper.selectStockForUpdate(goodsId);if(stock!nullstock.getStockNum()0){// 独占资源安全扣减绝对不会超卖、数据覆盖stock.setStockNum(stock.getStockNum()-1);stockMapper.updateById(stock);System.out.println(悲观锁扣库存成功行锁已释放);}}}2.6 ✅ 生产写法2数据库乐观锁版本号机制应用层代码锁高性能优选属于应用层代码锁范畴数据库仅存储version版本号字段无任何引擎自动锁机制所有并发冲突校验、版本比对、失败重试全部由业务代码实现。无数据库锁阻塞开销并发性能更好适合并发量大、数据修改冲突概率低的库存业务。第一步库存表手动新增version版本号字段数据库仅做存储无锁逻辑第二步代码层面实现版本号校验更新匹配成功才扣减冲突直接失败TransactionalpublicvoiddeductStockOptimistic(LonggoodsId){// 查询库存数据和当前版本号数据库无任何加锁操作StockstockstockMapper.selectById(goodsId);if(stock.getStockNum()0){// 更新核心条件商品id匹配 版本号一致证明数据未被其他线程修改introwsstockMapper.updateStock(goodsId,stock.getVersion(),stock.getStockNum()-1,stock.getVersion()1);// 更新行数为0说明数据已被修改并发冲突可代码手动重试下单if(rows0){thrownewRuntimeException(库存更新冲突重试下单);}}}2.7 数据库锁核心实操三连答疑生产必懂规避锁失效坑答疑1数据库加锁是代码加SQL还是数据库提前配置锁谁管控**一句话死记数据库无任何自动锁配置所有悲观锁、乐观锁全靠程序员代码手动实现。**MySQL数据库本身不会自动上锁、自动防超卖、自动处理并发冲突仅提供锁底层能力悲观锁能力在数据库引擎触发在代码SQL乐观锁全在代码架构层数据库只当数据存储计算器。代码不写锁逻辑数据库裸奔运行该超卖照样超卖。答疑2selectStockForUpdate是框架自带方法**明确答复完全自己手写Mybatis、Mybatis-Plus无任何自带for update锁查询方法。**框架自带查询都是普通无锁查询想要InnoDB行级悲观锁必须自定义Mapper方法、手写带for update的SQL否则锁完全不生效。答疑3悲观锁、乐观锁是MySQL自动处理还是代码处理MySQL只提供底层锁能力所有业务逻辑、冲突处理全靠代码悲观锁MySQL负责加行锁、事务结束释锁代码负责开事务、写加锁SQL乐观锁MySQL负责存版本号代码负责加字段、校验版本、处理冲突重试无全自动托管锁。三、第三种锁Redis分布式锁SpringCloud微服务集群高并发生产标配前面讲的Java本地锁、数据库锁都有各自的场景边界Java本地锁仅适用于单JVM单体实例集群环境完全失效数据库锁强一致性拉满但基于磁盘IO和事务日志高并发秒杀、高频防重场景性能瓶颈明显。而Redis分布式锁是微服务集群高并发场景下的核心并发协调方案专门解决跨JVM、跨服务多实例之间的资源互斥访问问题也是生产高并发业务必不可少的核心组件。很多新手只知道用Redis加锁但压根不懂Redis锁本质、不会区分锁类型、手写锁各种隐形bug频发、线上经常出现锁过期误删、死锁、业务超卖等问题。下面系统拆解Redis分布式锁核心概念、分类演进、精准选型、底层归属、代码实操、生产避坑和前面数据库锁四大维度对应对齐看完既能写代码、又能懂原理、线上绝不踩坑。3.1 什么是Redis分布式锁核心本质必懂Redis分布式锁核心定义基于Redis高性能内存读写特性、单命令原子执行机制在Java应用代码层面自行封装实现的分布式协调互斥机制。核心核心作用只有三个精准对标生产痛点解决跨JVM、跨微服务多实例的同一资源并发抢占问题统一集群全局互斥规则防止分布式定时任务重复执行、接口重复提交、秒杀商品超卖、缓存击穿等高并发线上事故仅做应用层并发协调不替代数据库事务强一致性只负责流量拦截和并发互斥。生产关键切记Redis本身没有原生内置“锁”专属数据结构和锁命令分布式锁不是Redis自带功能是开发者利用Redis原子命令、过期特性组合封装的代码设计模式所有锁逻辑、互斥规则全靠代码实现。3.2 Redis分布式锁常见类型按生产能力演进按需选用Redis锁不是只有一种简单排他锁根据业务复杂度、并发需求、调用场景分为五类生产99%业务只用基础排他锁和可重入锁复杂框架Redisson已全部封装无需手写底层。锁类型核心能力说明生产适用真实场景基础排他锁通过SET NX PX原子命令加锁DEL解锁同一时间只允许一个线程加锁成功最简单基础互斥能力简单接口防重提交、短周期分布式任务防重复执行、基础并发拦截可重入锁同一线程可多次重复获取同一把锁内部维护锁计数器解锁对应递减计数不会自己锁死自己嵌套方法调用、复杂业务链路多层加锁、服务内部多层调用互斥场景公平锁基于Redis队列实现按请求到达顺序排队依次获取锁遵循FIFO先进先出规则需要严格控制业务执行顺序、不能抢占插队的特殊调度场景读写锁读操作共享不互斥、写操作独占互斥大幅提升读多写少业务并发吞吐量系统配置刷新、公共缓存重建、基础数据高频查询低频修改场景红锁RedLock多台独立Redis实例投票机制实现高可用锁业内争议大、时钟漂移风险高极少生产使用除非极致高可用且能接受弱一致AP架构的特殊系统生产选型铁律永远不要手写各类Redis锁底层直接使用Redisson客户端所有锁类型、原子性、续期、防误删逻辑已全部封装开箱即用稳定可靠。3.3 精准适用生产场景与数据库锁核心选型对比再也不选错很多开发纠结到底用Redis锁还是数据库锁核心记住Redis锁管高并发协调拦截数据库锁管核心资金数据强一致兜底两者经常搭配使用各司其职。对比维度Redis分布式锁数据库锁悲观/乐观锁作用生效范围跨服务、跨实例、跨JVM集群全局互斥仅限单数据库实例、单数据表数据行层级并发响应性能极高内存级操作微秒级响应支持超高并发中等涉及磁盘IO、事务日志写入并发有阻塞开销数据一致性级别最终弱一致网络分区、超时可能短暂失效强一致性依托数据库ACID事务绝对保障核心典型业务商品秒杀防超卖、分布式定时任务防重、接口防刷防重复提交、缓存击穿防护、跨服务并发协调用户余额扣款、核心库存扣减、订单状态流转、资金对账核算、核心资产修改最终选型建议协调型场景首选要高性能、要扛并发、允许短暂数据不一致数据型场景首选涉及资金资产、必须强一致、事务多操作联动生产黄金选型口诀跨实例高并发协调拦截用Redis锁单库核心账务强一致兜底用数据库锁Redis挡99%无效并发数据库兜底100%数据安全。3.4 核心实操答疑Redis锁是原生自带改数据库还是改Redis配置和数据库锁逻辑对齐统一搞懂锁的归属、配置位置、生效原理避免配置改错、锁不生效。**Redis是否原生自带分布式锁**❌ 完全没有Redis只提供SET、DEL、Lua脚本等基础命令锁的互斥逻辑、过期释放、所有权校验全是代码封装**在哪里配置和触发锁**✅ 完全在Java业务代码中实现通过Redisson、RedisTemplate客户端发送命令无需修改数据库任何配置**需要额外改Redis核心配置吗**无需特殊配置仅建议基础优化开启AOF持久化防锁Key丢失、调整内存淘汰策略避免锁Key被LRU误删**锁数据存在哪里**存储在Redis内存中结构为锁Key业务唯一标识、锁Value线程唯一ID防误删、TTL自动过期时间防死锁。3.5 Java代码两种实现方式手写懂原理生产只用Redisson3.5.1 手写极简版Redis锁仅学习理解原理生产绝对禁止上线新手必须看懂手写版踩坑点明白为啥生产不能自己造轮子核心要保证加锁原子性、解锁校验所有权、防止误删他人锁。// ❌ 错误致命写法加锁和设置过期时间分两步非原子服务宕机必死锁if(redisTemplate.opsForValue().setIfAbsent(distribute:lock:task,lock)){redisTemplate.expire(distribute:lock:task,30,TimeUnit.SECONDS);// 非原子极易死锁try{/* 业务逻辑 */}finally{redisTemplate.delete(distribute:lock:task);}}// ✅ 正确原子手写版仅学习生产不用ServicepublicclassTaskLockService{AutowiredprivateStringRedisTemplateredisTemplate;privatestaticfinalStringTASK_LOCK_KEYdistribute:lock:schedule:task;publicvoidrunScheduleTask(){// 定义唯一标识防止误删其他线程锁StringlockUuidUUID.randomUUID().toString();// 原子加锁不存在则设置自动过期30秒一步完成防死锁BooleanlockSuccessredisTemplate.opsForValue().setIfAbsent(TASK_LOCK_KEY,lockUuid,30,TimeUnit.SECONDS);// 加锁失败直接跳过任务防止重复执行if(!Boolean.TRUE.equals(lockSuccess)){System.out.println(其他服务正在执行定时任务本机跳过);return;}try{// 上锁成功执行业务定时任务逻辑System.out.println(本机获取分布式锁成功开始执行定时统计任务);// 此处替换真实业务数据统计、订单对账、批量数据同步等}finally{// 解锁必须校验当前线程所有权绝不误删别人的锁StringcurrentUuidredisTemplate.opsForValue().get(TASK_LOCK_KEY);if(lockUuid.equals(currentUuid)){redisTemplate.delete(TASK_LOCK_KEY);System.out.println(任务执行完成释放分布式锁);}}}}3.5.2 生产标准唯一写法Redisson分布式锁线上直接复制上线手写锁存在锁续期、可重入、公平调度、异常容错等无数短板生产统一使用Redisson内置看门狗自动续期、锁所有权校验、可重入机制、异常自动释锁零踩坑。第一步引入Maven依赖!-- Redisson分布式锁核心依赖SpringBoot无缝整合 --dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.25.0/version/dependency第二步生产业务落地代码自带看门狗防锁过期无需手动续期ServicepublicclassRedissonTaskLockService{// 注入Redisson核心客户端自动装配无需手动配置AutowiredprivateRedissonClientredissonClient;// 按业务维度定义全局唯一锁Key业务隔离避免误锁privatestaticfinalStringTASK_LOCK_KEYdistribute:lock:schedule:task:statistic;publicvoidrunScheduleTask(){// 获取可重入分布式锁实例RLocklockredissonClient.getLock(TASK_LOCK_KEY);try{// 阻塞抢占锁默认开启看门狗机制业务未执行完自动续期30秒防止锁提前过期lock.lock();// 上锁成功仅一台服务执行业务逻辑System.out.println(Redisson分布式锁获取成功单机执行定时对账统计任务);// 核心业务逻辑订单对账、数据批量同步、库存预热、定时统计等}finally{// 安全解锁仅当前线程持有锁才解锁防止误删、重复解锁报错if(lock.isHeldByCurrentThread()){lock.unlock();System.out.println(任务执行完毕安全释放Redisson分布式锁);}}}}3.6 生产Redis分布式锁避坑指南amp;最佳实践线上必看杜绝故障线上常见痛点问题问题产生核心原因生产标准解决方案锁提前过期业务没执行完锁就释放业务执行耗时超过锁TTL过期时间其他线程直接抢占锁使用Redisson默认看门狗自动续期无需手动设置过期时间自动按需延长锁时长线程误删其他线程持有的锁线程A业务超时锁过期线程B加锁成功线程A执行完误删B的锁解锁强制校验锁Value线程唯一标识Redisson已内置自动校验无需手动编写服务宕机未手动解锁造成死锁服务突然宕机finally解锁代码未执行锁永久存在所有锁必须设置TTL过期时间Redisson看门狗宕机自动失效杜绝永久死锁Redis锁与数据库事务混用数据不一致Redis锁提前释放数据库事务还未提交并发流量穿透超卖锁范围全覆盖事务先加Redis锁 → 执行业务提交DB事务 → 最后释放锁不同业务锁Key冲突互相影响多个业务共用同一个锁前缀出现业务互相锁住阻塞锁Key按业务精细隔离lock:order:{订单ID}、lock:task:{任务ID}精准互不干扰3.7 架构师终极总结Redis分布式锁不是Redis原生功能是应用层代码实现的分布式协调工具高并发集群防重、秒杀限流用Redis锁扛流量核心资金账务、库存扣款用数据库锁做兜底生产坚决摒弃手写Redis锁统一使用Redisson开箱即用配合看门狗续期、所有权校验规避所有线上隐形坑Redis锁拦并发、数据库锁保数据双锁架构是微服务生产最稳最优方案。四、生产终极锁选型对照表新手直接查表永不选错锁类型部署环境典型真实业务场景生产推荐指数Java本地锁synchronized/Atomic单体SpringBoot单实例内存接口计数、本地简单限流、单服务线程同步⭐⭐⭐⭐⭐单体必用数据库锁悲观/乐观锁集群/微服务所有环境下单扣库存、用户余额扣款、订单核心账务强一致兜底⭐⭐⭐⭐⭐核心账务必用Redis分布式锁SpringCloud微服务集群高并发秒杀、分布式定时任务、接口防重复提交⭐⭐⭐⭐⭐集群高并发必用五、老开发最终一句话总结牢记不踩锁所有坑普通简单CRUD业务只用局部变量一辈子不用加任何锁画蛇添足易出问题单体项目内存临时计数就用Java本地锁简单够用、性能拉满、无冗余依赖集群环境核心账务扣库存、资金扣款就用数据库锁InnoDB行锁兜底、稳定不超卖微服务集群高并发秒杀、分布式定时任务就用Redis分布式锁性能最优、集群互斥。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2561505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…