news 2026/9/28 8:30:01

锁的分类全解析:从互斥锁到分布式锁,一篇讲透

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
锁的分类全解析:从互斥锁到分布式锁,一篇讲透

前阵子技术群里有人问:常见的锁到底怎么分类?结果回答五花八门,有人报互斥锁、读写锁,有人直接把数据库的行锁表锁拍上来,还有人反问“你是说Win11锁屏壁纸不更新那个锁吗?”十来个人聊了半天,最后谁也没给出一个能直接拿去用的答案。这个场景其实很典型——锁这个概念,散落在并发编程、数据库、分布式系统、操作系统、移动端刷机甚至办公软件里,每个领域的人都只熟悉自己那一亩三分地,串不起来。

做开发和维护线上系统这十年,我越来越觉得“锁”是计算机体系里最绕、也最容易被低估的概念。它无处不在:CPU指令级的自旋锁、JVM里的synchronized、MySQL的Record Lock、Redis里的分布式锁,再到你电脑锁屏、Excel保护单元格、手机解锁BootLoader,本质都是同一个思想——通过某种机制,保证资源访问的唯一性、安全性和合法性。这篇文章就把散落各处的常见锁分类串起来,按领域拆开讲,再带上排查思路和面试题速记。不管你是准备跳槽面试、正在查线上死锁,还是单纯想搞懂身边这些“锁”,应该都能捞到点有用的。

1. 一张图看懂“锁”的本质

1.1 锁的三个基本问题

我排查各种锁问题久了,发现无论什么锁,先回答三个问题,思路就清晰了:锁保护的是什么资源?谁有机会持有这个锁?什么条件下释放?这三个问题能覆盖从门锁到分布式锁的几乎所有场景。

拿家里的门锁举例,保护的是房间空间,持有者是拿着钥匙的人,释放条件是钥匙正确转动锁芯。换到数据库行锁,保护的是那一条记录,持有者是当前事务,释放条件是事务提交或回滚。再看Windows锁屏,保护的是你的桌面会话,持有者是登录用户,释放条件是输入正确的密码或PIN。是不是同一套逻辑?

这三要素看着简单,但很多线上故障都是因为其中一个要素没设计清楚。比如Redis分布式锁如果忘了加过期时间,那就是“释放条件”缺失,线程挂了锁永远不会释放;MySQL里事务忘了提交,就是“持有者”迟迟不释放,后面所有更新排队等。所以学锁分类,先把这个心智模型建好,比死记概念有用得多。

1.2 从机械锁到并发锁:锁的两条分类线索

分类方式有很多种,我觉得最实用的是按领域和按策略两个维度切。

按领域分,常见的有:物理锁(门锁、车锁)、并发编程锁(互斥锁、读写锁、自旋锁)、数据库锁(行锁、表锁、间隙锁)、分布式锁(Redis分布式锁、ZooKeeper锁)、操作系统会话锁(Windows锁屏、Ubuntu锁屏)、固件硬件锁(手机BL锁、SD卡锁)、办公文件锁(Excel保护、压缩包密码)。

按策略分,常见的有:悲观锁与乐观锁、阻塞锁与非阻塞锁、公平锁与非公平锁、可重入锁与不可重入锁。这些策略并不是某个领域专属,而是可以横切到所有领域。比如悲观锁既可以是数据库的SELECT ... FOR UPDATE,也可以是并发编程里直接加mutex;乐观锁既可以是版本号机制,也可以是Redis Lua脚本里的条件判断。

后面的章节,我就按领域展开,在每个领域里再用策略维度细化,这样既能系统化理解,面试时也能对答如流。

2. 并发编程里的锁:从互斥锁到事件锁

2.1 互斥锁、读写锁、自旋锁:三类最基础的锁

并发编程里的锁,核心目标是防止多个线程同时操作共享资源导致数据错乱。最基本的互斥锁(Mutex)我就不多废话了,同一时刻只允许一个线程进入临界区,就像公司里只有一个会议室,谁申请到谁用,用完释放。

读写锁(ReadWriteLock)是互斥锁的优化版,核心规则是“读读共享、写写互斥、读写互斥”。适合读多写少的场景,比如配置中心、路由表、商品详情缓存。如果写操作频繁到和读操作差不多,读写锁反而可能比普通互斥锁还慢,因为要维护读计数和写等待两个状态。选型的时候先用数据说话,别只看它听起来高级。

自旋锁(SpinLock)就比较特别了,它拿不到锁的时候不进入睡眠,而是在原地循环检测锁状态,直到获取成功。好处是避免了线程切换开销,坏处是白白烧CPU。临界区极短、多核环境下用得很爽,比如内核里保护某个寄存器的读写;但如果临界区里干了耗时操作,那别的线程全在空转,CPU直接被拉满。我见过一次线上事故,就是有人在自旋锁保护的代码里写了日志刷新,结果8核CPU全部打满。

2.2 可重入锁:为什么同一个线程还能再拿同一把锁

可重入锁是容易被忽略但极其重要的概念。简单说,同一个线程可以重复获取同一把锁,每获取一次计数加一,每释放一次计数减一,计数归零才算真正释放。之所以要这么设计,是因为很多场景下,一个线程在执行加锁代码时,内部可能通过方法调用再次进入同一个临界区。

C++里有std::recursive_mutex,Java里synchronized和ReentrantLock都是可重入的。不可重入的锁会有什么问题?你自己写一个简单的mutex类,没有重入计数,然后在一个加锁方法里调用另一个加锁方法,就会自己把自己锁死。

Java面试常问synchronized和ReentrantLock的区别,其中一大关键就在可重入性和中断响应上。ReentrantLock还支持公平锁、尝试非阻塞获取锁(tryLock)、超时获取,这些synchronized都没有。实践里如果只是简单临界区,synchronized足够;需要超时控制或者公平调度的时候再换ReentrantLock。

2.3 System.out.print到底有没有锁

这问题看起来刁钻,其实很有意思。System.out是一个PrintStream对象,它的print和println方法内部是synchronized修饰的,所以多线程同时调用时,单行输出不会出现字符交错——这是有锁的。但要注意,这个锁只能保证一次方法调用的原子性,如果你写出这样的代码:

System.out.print("user id: "); System.out.println(user.getId()); System.out.print("user name: "); System.out.println(user.getName());

两个线程交叉打印时,虽然每行内部不会乱,但多行之间完全可能互相穿插,日志就变成“user id: 1001 user name: zhangsan”这种错乱结果。所以“有锁”和“输出整体有序”是两码事。生产中不建议靠System.out打日志,真要打也要自己加一个独立的互斥锁,或者直接用日志框架,把整条日志拼好再一次性输出。

2.4 游戏开发中的事件锁:锁的是队列,不是逻辑

游戏开发里常说的“事件锁”,其实不是某种新锁类型,而是事件驱动模型里配合使用的同步机制。典型场景是:逻辑线程产生玩家操作事件,渲染线程消费事件,修复两个线程不能直接访问同一个数据结构的问题。

我见过一个比较常见的写法:用互斥锁保护一个事件队列,生产者push,消费者pop,事件本身不会因为线程竞争而错乱。但要注意的是,锁只保护队列的存取,不保护事件处理逻辑。你不能在持锁状态下执行复杂技能逻辑,否则渲染线程卡顿,玩家立刻能感受到。更进阶的做法是双缓冲队列:线程A写入pending队列,业务线程通过swap拿到当前批次数据,这样锁的粒度就非常小了。游戏引擎里的“帧事件锁”本质上也是这个套路——在一个帧周期内收集事件,帧末统一派发,尽量避免频繁锁竞争。

3. 数据库锁:MySQL面试必问的分类体系

3.1 乐观锁与悲观锁:两种并发控制思想的对比

数据库锁是面试重灾区,每次聊到MySQL锁分类,逃不掉乐观锁和悲观锁。悲观锁的思维方式是“很可能有人改数据,先锁住再说”。在MySQL里就是SELECT ... FOR UPDATE,事务A查询商品库存时直接锁行,事务B的更新只能等A提交。这种方式写冲突频繁时很安全,但并发低、容易阻塞。

乐观锁的思路刚好相反:“不锁数据,提交时再检查有没有被别人改过”。实现方式通常是版本号或时间戳,更新语句带上条件判断:

-- 悲观锁示例 BEGIN; SELECT stock FROM product WHERE id = 1 FOR UPDATE; UPDATE product SET stock = stock - 1 WHERE id = 1; COMMIT; -- 乐观锁示例 UPDATE product SET stock = stock - 1, version = version + 1 WHERE id = 1 AND version = 5; -- 如果影响行数为0,说明version已被其他事务修改,需要重试

乐观锁适合读多写少的场景,比如论坛点赞、用户资料更新。代码里如果发现更新行数为0,不要闷头继续,要返回失败或者重新读版本号再试。另外提醒一句:乐观锁不是完全没有锁成本,它只是在冲突发生时才付出代价,而且这个代价通常是一次重试;如果业务写冲突很频繁,反而应该用悲观锁。

3.2 InnoDB的行锁、表锁、间隙锁与MVCC

MySQL InnoDB引擎的锁,按粒度可以分为行锁、表锁和页锁,但实际面试更关注行锁和表锁。行锁只锁被访问的索引记录,并发粒度小;表锁锁整张表,粒度大但开销小,常见于MyISAM或某些DDL操作。

InnoDB行锁里还有细分:Record Lock锁单条记录,Gap Lock锁一个区间但不管记录本身,Next-Key Lock是Record Lock和Gap Lock二合一,锁住左开右闭区间。InnoDB默认的隔离级别是Repeatable Read,会用Next-Key Lock来防止幻读。比如你执行SELECT * FROM orders WHERE amount > 100 FOR UPDATE,其他事务要想在amount 50到150之间插入一条记录,会被间隙锁挡住。

MVCC是另一个需要理解的概念。InnoDB通过undo log维护多版本数据链,配合ReadView实现不加锁的快照读。普通SELECT不加锁,走MVCC;SELECT ... FOR UPDATE、UPDATE、DELETE是当前读,需要加锁。所以MySQL的隔离性,是“MVCC + 锁”一起撑起来的。

这里一定要提一个排查中老遇到的问题:为什么一个看起来只更新一行数据的SQL,最后把整张表堵住了?最常见的原因是更新条件没走索引。InnoDB是索引组织表,更新时如果走全表扫描,它会在扫过的每一行上都需要加锁,实际锁范围接近整张表。热搜词里的“mysql锁表”,十有八九就是这个场景。

3.3 线上锁表排查与MySQL锁相关面试题沉淀

线上遇到锁表,先用这几条SQL看现场:

-- 查看当前所有事务 SELECT * FROM information_schema.innodb_trx\G; -- 查看锁等待关系 SELECT * FROM information_schema.innodb_lock_waits; -- 查看具体锁信息(InnoDB旧版;8.0也可以用performance_schema.data_locks) SELECT * FROM information_schema.innodb_locks;

排查思路很固定:先看innodb_trx里有没有事务一直处于LOCK WAIT或长时间RUNNING,拿到trx_mysql_thread_id之后去SHOW PROCESSLIST里看它执行的SQL和状态,然后顺着innodb_lock_waits的blocking_trx_id找阻塞源头。如果死者是一个长事务,但已经不影响任何业务,可以KILL对应线程;如果还有业务在跑,就要评估一下杀掉事务的代价。

面试题方面,MySQL锁的分类是个送分题,但要答得有条理:按粒度分表锁、行锁、页锁;按思想分乐观锁、悲观锁;按操作方式分共享锁(S锁)、排他锁(X锁);InnoDB还有Record Lock、Gap Lock、Next-Key Lock。死锁四个必要条件也得背下来:互斥、请求与保持、不可剥夺、循环等待。排查死锁用SHOW ENGINE INNODB STATUS,找到LATEST DETECTED DEADLOCK段落,里面会直接打印两条事务的SQL。

4. 分布式锁:Redis方案、落地场景与高频面试题

4.1 为什么单机锁不够用

很多人刚学完synchronized,转头遇到分布式环境就懵了:明明代码里加了锁,为什么库存还是超卖?原因很简单,synchronized锁的是JVM进程内的对象监视器,微服务部署了多个实例,每个实例各有各的JVM,锁根本不在同一个空间里。

分布式锁要解决的问题就是跨进程、跨节点的互斥。典型使用场景包括:多实例定时任务抢单(同一个任务只允许一个节点执行)、库存扣减、分布式事务中的幂等控制、多机缓存刷新。面试官问“分布式锁使用场景”,能说出这三四个例子就够有说服力了。

4.2 Redis分布式锁的落地步骤与Lua脚本

Redis实现分布式锁,最基础也最常用的方案是SET key value NX PX 过期时间。NX保证只有当key不存在时才能设置成功,PX设置锁的自动过期时间,防止持有者宕机后锁永远不释放。

但释放锁的时候不能直接DEL,因为你可能把别人刚获取的锁给删了。正确姿势是先用GET拿到锁里的value,和自己当初写入的唯一标识比较,一样才删。为了把这步做成原子操作,要用Lua脚本:

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

这个脚本我在生产环境一直用,配合每个请求生成的UUID作为value,可以避免误删锁。加锁时也一样,不要分成两步走(先SETNX再EXPIRE),要一条命令搞定,否则加锁成功下一秒进程崩溃,锁就变成永不过期的死锁了。

如果是Java项目,直接用Redisson会更省心,它内部有个“看门狗”机制,默认锁租期30秒,业务没执行完就自动续期,执行完释放,最大程度避免“锁过期了业务还在跑”的尴尬。但需要明确一点:自研Redis分布式锁最容易踩的坑就是过期时间设置不当。设太短,长任务锁提前释放,另一台机器冲进来;设太长,持有者宕机后要等很久才能恢复。所以要么根据业务预估时间设置,要么就走Redisson这种自动续期的方案。

4.3 分布式锁的经典坑与三种实现方案对比

Redis单节点分布式锁有一个理论上的漏洞:如果Redis主节点宕机切换,新的主节点可能没有刚才的锁数据,另一个线程还是能成功加锁。为了解决这个问题,Redis官方提出了Redlock算法——向多个独立Redis节点依次加锁,超过一半成功才算获取成功。但Redlock本身也有争议,很多资深工程师认为它在极端场景下依然无法保证绝对安全,还需要考虑时钟跳跃等问题。

实际业务中,我建议的选型逻辑是这样的:

实现方案优点缺点适用场景
Redis SETNX + Lua性能高、实现简单主从切换可能丢锁,需要自己处理续期大部分业务场景,缓存类、抢购、任务调度
数据库唯一键/悲观锁可靠、不需要额外组件性能差,事务时间影响吞吐低频、对一致性要求极高的内部系统
ZooKeeper临时顺序节点一致性最好,无过期续期问题引入ZK组件,运维成本高对一致性要求极高的分布式协调场景

面试问“分布式锁怎么实现”,你把上面三种答出来,再说清楚各自取舍,基本就是高分了。另外要记住一个思想:能用幂等设计和数据库唯一约束解决的事,压根别引入分布式锁。锁是最后手段,不是第一选择。

5. 操作系统与终端锁:锁屏的一切实用玩法

5.1 Windows锁屏:聚焦壁纸、自动锁屏与控制台

操作系统的锁屏,本质是保护正在登录的桌面会话。按下Win+L立刻锁屏,配置好的话唤醒后需要重新输入密码。很多普通用户问的锁屏问题,其实都是设置层面的小坑。

Windows聚焦锁屏壁纸不自动更换,常见原因有三个:聚焦服务被禁用、聚焦缓存损坏、组策略里被关闭。排查时先去“服务”里看ContentDeliveryManager是否启用,接着删除缓存文件(位置在C:\Users\用户名\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets),重新启动聚焦。如果还是不行,检查是否被公司域策略接管,个人电脑一般没那么复杂。

Win10/Win11“自动锁屏时间设置后被系统覆盖”也是一个经典现象。原因是Windows的锁屏触发有三层:电源计划里的“唤醒后需要登录”、屏幕保护里的“在恢复时显示登录屏幕”、以及“动态锁”。三处设置如果互相冲突,会出现你明明设置了10分钟自动锁屏,结果没生效。建议在三处统一设置,优先改屏幕保护选项,因为Win11的已知问题比较多。企业电脑还会被组策略的“不显示锁屏界面”覆盖,这时本地设置修改了也没用,需要管理员处理。

热搜里还有一个挺有意思的提问:“重启后能不能先进桌面把开机启动软件全部跑完再锁屏?”技术上可行,用计划任务设置延迟锁屏时间,或者在启动脚本里执行完再触发锁屏。但我要提醒一句:开机启动软件全部跑完再锁屏,这段时间系统处于无保护状态。如果是公共电脑或办公电脑,这是一个安全隐患,别为了自己方便降低安全底线。

5.2 Ubuntu与WindTerm的锁屏设置

Ubuntu桌面环境(GNOME)关闭自动锁屏和锁屏密码,图形界面走“设置-隐私-屏幕锁定”,把“自动锁定屏幕”和“挂起后锁定屏幕”关掉。命令行可以用gsettings:

gsettings set org.gnome.desktop.screensaver lock-enabled false gsettings set org.gnome.desktop.screensaver idle-activation-enabled false

WindTerm是我常用的一款开源终端工具,很多同学问“WindTerm锁屏密码”怎么设置。其实在WindTerm的“Settings”里的“Security”下有“Lock Screen”选项,可以设置工具启动或手动锁定时需要输入全局密码,用来防止别人在你离开时直接看到终端内容,这属于终端会话级别的锁。

这些设置仅针对个人电脑有意义。办公环境里,域策略或安全合规通常强制要求锁屏,私自关闭不被允许,也别这么做。说到底,锁屏是最后一道物理防线,睡觉前电脑开在那,谁都能翻你的聊天记录,那才叫真的社死。

6. 移动端与硬件锁:从BL锁到门禁锁控板

6.1 BL锁:刷机路上那道门槛

手机圈的BL锁,全称是BootLoader锁,控制的是设备引导加载程序能不能被第三方替换。小米、华为、一加这些厂商普遍默认锁定BootLoader,防止用户刷入非官方系统后破坏安全启动链路。

很多热搜词比如“小米10s秒解bl锁”“红米note13pro解bl锁”“小米6强解bl锁”都是围绕这个话题。正规解锁流程其实很固定:开发者选项里绑定小米账号并申请解锁资格,等待系统审核,然后用官方Mi Unlock工具解锁。整个过程不复杂,但需要时间,小米一般要求账号使用时长和社区等级达标再解锁。

“秒解”“强解”这两个词背后通常是用漏洞或非官方手段绕过验证,风险很高,常见后果包括:官方解锁资格被封、设备变砖、指纹支付等安全功能失效。我不推荐任何人用这类方式。如果你确实需要刷机,老老实实走官方解锁流程,花几天时间换设备稳定,比贪快然后翻车划算多了。

6.2 账户锁与设备找回安全

账户锁在手机上通常指FRP(Factory Reset Protection)或厂商云账户锁,也就是说,即使有人把手机恢复出厂设置,也会被要求输入原机主的账号密码才能继续激活。这是最有效的防盗机制之一。

所以“华为强制解除原主id锁”“刷账户锁华为”这类搜索既不合法也不符合社会公序良俗。如果是自己的手机,正常路径是找回账号密码;如果账号真找不回来,就提供购买凭证、发票、盒子上的IMEI号,联系官方客服走人工解绑。我处理过几次帮朋友解锁的情况,凭证齐全,官方客服一般当天就能处理,没必要走灰色渠道。

账户锁之所以存在,是因为手机已经变成个人信息和移动支付的中心。试想一下,如果任何捡到手机的人都能通过恢复出厂设置绕过账户锁,那手机丢失等于银行卡丢失。这个锁千万别想着“破解”,它是在保护我们自己。

6.3 SD卡锁、共享充电宝和门禁锁控板

SD卡出现“内部寄存器锁死”其实不常见,多数是误读。SD卡卡体侧边有一个写保护开关,拨到LOCK位置后只能读不能写,这是物理写保护锁。如果开关没拨错还是提示写保护,通常问题是劣质读卡器把状态引脚识别错误了,换一个读卡器或者换一台电脑一般能解决。真正寄存器锁死的案例往往和卡损坏有关,备份数据后尝试格式化,不行就只能换卡。

共享充电宝卡住不能取,原因基本是订单未结束或者卡扣机械故障。网上能搜到各种“解锁教程”,但我不建议去撬、砸,共享充电宝属于租赁物,破坏会触发赔偿,而且卡扣里面是电磁锁,强行拽会损坏机器。正确操作是联系客服确认订单状态,让后台释放锁,或者按归还按钮重新触发一次机械复位。

门禁锁控板协议是另一个硬核话题,主要在弱电工程和智能家居领域。锁控板控制的通常是电磁锁、电插锁或电机锁,核心是收到合法开门信号后释放锁舌。工程上做门禁系统,要关注通信协议加密、防重放攻击、断电自动开锁还是自动闭锁。很多项目为了省成本用明文协议传输用户ID,别人抓包后就能模拟开门指令,安全形同虚设,这点踩过坑的人应该都懂。

7. 办公与文件锁:Excel保护、压缩包加密与文件占用

7.1 用EasyExcel导出时如何只锁定部分单元格

Excel里的“保护工作表”功能本质是一个全表锁。默认情况下所有单元格的Locked属性都为true,一旦执行ProtectSheet,整个工作表都不可编辑。

很多Java后端用EasyExcel导出模板时会遇到一个问题:导出后工作表被完全锁死,但希望A列能填数据,B列只能看。原因就是没提前设置可编辑区域的Locked属性。正确做法是:在写导出时,给那些允许编辑的列设置独立单元格样式,并把setLocked(false),再对Sheet执行保护。示意代码如下:

WriteCellStyle contentStyle = new WriteCellStyle(); contentStyle.setLocked(false); // 注册到你希望可编辑的列 // 最后执行 sheet.protectSheet("密码");

注意一个细节:如果整表保护了,再想“允许用户编辑部分区域”,还要考虑sheet级别能不能正常插入行。常规模板导出场景,前后列样式都要统一设置,否则同一列有10行可以编辑、后面10行又锁住,用户会一头雾水。实践里建议先用Excel手动做一份模板验证,再用EasyExcel去复现。

7.2 压缩包加密与文件被占用的“隐形锁”

压缩包“被锁定不能修改”有两种情况。一种是加了密码,ZIP或RAR的密码本质是内容加密锁,不知道密码几乎无法正常解压修改。网上说的暴力破解对强密码没有意义,不如好好回忆密码,或者检查浏览器保存的密码记录、笔记软件里的备注。另一种是文件权限问题,右键属性-安全,给当前用户分配完全控制权限就能解决。

还有一种非常常见的“文件被锁”是操作系统层面的文件占用锁。Windows下删除某个Excel或图片时提示“文件已在另一个程序中打开”,其实是有进程持有了该文件句柄。打开任务管理器,进入“性能-打开资源监视器-CPU-搜索句柄”,输入文件名就能找到占用进程。Linux下更简单:

lsof /path/to/file fuser -k /path/to/file

这类文件锁和并发编程里的互斥锁本质同源——都是“当前资源被某持有者占用,其他访问者需要等待”。所以排查思路完全可以复用前面说的三要素法。

8. 问题速查与面试题简答

8.1 高频问题定位速查表

现象可能原因排查与应对
MySQL锁表,业务SQL全部卡住长事务未提交、间隙锁互等查innodb_trx定位阻塞事务,评估后kill或优化SQL
Redis分布式锁提前释放过期时间设短,业务未完成使用Redisson看门狗续期,或设置合理过期时间
Redis锁误删别人锁释放时直接DEL用唯一value + Lua脚本先比对后删除
Windows锁屏壁纸不更新聚焦服务禁用、缓存损坏启服务、清缓存、检查组策略
Win11自动锁屏设置失效屏保、电源、组策略冲突统一三处设置,优先改屏保恢复时锁定
Excel保护工作表后部分区域无法编辑可编辑区域没取消Locked导出时给可编辑列设置setLocked(false)
文件提示被占用无法删除进程持有文件句柄Windows资源监视器找句柄,Linux用lsof
手机BL锁无法走第三方解锁官方安全限制走官方申请解锁流程,不要强解
SD卡写保护无法解除物理开关或读卡器故障拨动开关、更换读卡器,再考虑格式化

8.2 面试题简答速记

MySQL锁分类简答:

  • 按粒度:表锁、行锁、页锁
  • 按思想:乐观锁、悲观锁
  • 按兼容性:共享锁、排他锁
  • InnoDB特有:Record Lock、Gap Lock、Next-Key Lock

乐观锁为什么不需要数据库锁?因为它不直接锁资源,而是用版本号或时间戳做CAS检测,提交时发现冲突再重试或报错。这里要注意:优秀的乐观锁方案在并发高峰下也会出现大量重试,所以要在业务层设个重试上限。

分布式锁三种方案对比是送分题,前面表格就是标准答案。再加一句Redlock的争议:理论上有时钟跳跃问题,工程上单节点Redis配合过期时间、Lua脚本和看门狗其实已经能覆盖绝大多数业务。

死锁排查一句话版本:用SHOW ENGINE INNODB STATUS看死锁日志;分布式场景用Redisson等客户端自带的Redlock看门狗;如果是自研锁,重点检查获取锁的嵌套顺序是否一致。

8.3 实战避坑经验

我在一线写代码和救火的经验,总结成三条。第一条:所有“锁”问题,先按三要素拆解再动手,别一上来就翻代码。第二条:能用数据库唯一键或幂等设计解决的问题,别引入分布式锁;能用单机读写锁解决的问题,别上分布式锁。每加一层锁,就多一层不确定性和故障点。第三条:锁的释放逻辑一定要写在finally或Lua脚本里,避免任何异常路径导致锁残留。

我平时排查线上超时类故障时还养成一个习惯:先在问题描述里把“锁的资源、持有者、释放条件”写下来,很多时候写着写着,病因自己就冒出来了。比如“库存扣减超时”这个问题,写完三要素就发现不是SQL慢,而是同一个用户的多笔请求在分布式锁上串行排队,锁的粒度太粗了。把锁从用户维度改成SKU维度后,吞吐量直接翻倍——锁的分类和粒度设计,才是真正的性能分水岭。

最后再分享一个小技巧:遇到不熟悉领域的锁名词,先别急着搜“是什么”,而是搜“在这个场景里锁住了什么、谁持有、怎么释放”。用这个框架去看MySQL的Next-Key Lock、Redisson的看门狗、手机账户锁、门禁锁控板,会发现它们只是在不同介质上重复着同一套保护逻辑。理解到这个层面,所谓“常见锁分类”就不再是需要背的资料,而是一个随时可以调用的工程思维。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 8:29:32

上海雷蒙威手表网站保姆级教程:搞定域名服务器只需3步

上海雷蒙威手表网站保姆级教程:搞定域名服务器只需3步 域名解析报错、服务器配置一团糟?别慌,这是建站新手最头疼的坑。 很多做品牌官网的朋友,盯着后台那些复杂的 DNS 记录和 Nginx 配置文件就头大。其实,把上海雷蒙威手表网站这类品牌站搭好,核心逻辑并不复杂,只是没人把细节掰碎了讲。…

作者头像 李华
网站建设 2026/9/28 8:29:25

快手做电商需要投资多少钱?避坑源码下载全解析

快手做电商需要投资多少钱?避坑源码下载全解析 昨天凌晨两点,我盯着后台监控大屏,心跳差点停跳。一个刚上线半年的独立站,首页突然跳出一堆乱码和赌博广告,服务器CPU直接飙红。那一刻我才意识到, 网站被黑挂马不知道怎么办…

作者头像 李华
网站建设 2026/9/28 8:29:13

字节序实战指南:从内存布局到跨平台数据交换

1. 为什么“字节序”不是玄学,而是每天都在咬你一口的硬伤你写完一段C代码,把一个int32_t变量赋值为0x12345678,用printf("%x", val)打印出来,屏幕上稳稳当当地显示12345678——你松了口气,觉得一切正常。可…

作者头像 李华
网站建设 2026/9/28 8:28:37

分子几何表征进阶:等变图网络与构象生成实践

最近在整理做分子几何表征项目的思路,想把这个过程中的关键取舍和经验捋一遍。这个主题叫“不止生成:迈向更好的分子几何表征”,说白了就是:我们不只是想让模型生成一个看起来合理的分子三维构象,更重要的是让这些几何…

作者头像 李华
网站建设 2026/9/28 8:28:32

网站内容建设总结图解步骤:3个实战案例教你防挂马

网站内容建设总结图解步骤:3个实战案例教你防挂马 网站被黑挂马,后台还能登录但前台全是博彩广告,这种深夜惊魂时刻,90%的站长都经历过。别慌,这不是玄学,是内容建设流程里的漏洞在发威。今天用 图解步骤 拆解一套 网站内容建设总结 方法,从代码注入到权限隔离,手把手教你把风险扼杀在摇篮里。…

作者头像 李华