分布式并发业务场景:别动不动就加分布式锁!

54 阅读3分钟

沉默是金,总会发光

大家好,我是沉默

在分布式系统的世界里,高并发就像是一场没有硝烟的战争

——订单创建、库存扣减、支付回调、超时关单……

每一个环节都可能在同一毫秒内被成百上千的请求冲击。

很多开发者的第一反应是:
“加个分布式锁吧!”

但锁不是万能,甚至可能拖慢系统。

真正的高手,会先分析业务场景,精准选择最优解

——有时不用锁,反而更优雅、更高效

今天,我就带你拆开高并发的“黑箱”,看看 悲观锁、乐观锁、无锁方案 是如何在不同战场各显神通,让你选出最优解。

**-**01-

业务场景分析

解决并发问题,第一步不是选锁,而是:

  1. 梳理业务场景
  2. 找到该场景下的冲突点
  3. 再决定是否加锁、加什么锁

有些场景甚至不需要锁,只靠 一条 SQL 就能解决,而且还是性能最优解。

- 02-

并发防控的三大方案

无论方案多花哨,本质上就三类:

方案核心思想优点缺点典型场景
悲观锁先加锁再操作防冲突强,fail-fast降并发、锁等待高频写、冲突多
乐观锁先操作再校验版本高并发友好冲突高时失败多冲突低、可重试
无锁方案靠数据库天然行锁无业务锁、快场景有限秒杀、不超卖
  1. 悲观锁(Pessimistic Lock)

假设冲突频繁发生,先拿锁再执行。
案例:订单创建(高并发、幂等控制)

@DistributeLock(keyExpression = "#req.identifier", scene = "ORDER_CREATE")public OrderResponse create(OrderCreateRequest req) {    orderValidatorChain.validate(req);    // 库存扣减 + 创建订单}

适合:写多读少、冲突高、需 fail-fast
2. 乐观锁(Optimistic Lock)

假设冲突概率低,先处理再用版本号做 CAS 校验。
案例:支付回调(并发低、有状态机)

UPDATE trade_orderSET lock_version = lock_version + 1,    order_state = #{orderState}WHERE order_id = #{orderId}  AND lock_version = #{lockVersion}

适合:读多写少、可重试、冲突低

3. 无锁方案(SQL 行锁)

业务代码不显式加锁,直接靠 MySQL 行锁串行化更新。
案例:秒杀库存扣减(只关心不超卖)

UPDATE collectionSET saleable_inventory = saleable_inventory - #{quantity}WHERE id = #{id}  AND saleable_inventory - frozen_inventory >= #{quantity}

适合:极高并发、关注正确性而非顺序

- 03-

如何选?

  • 写多读少、冲突高 → 悲观锁

  • 读多写少、冲突低 → 乐观锁

  • 对并发不敏感,只需防止数据错误 → 无锁(SQL 行锁)

图片

**-**04-

总结

你的系统,可能正因为「乱加锁」在白白牺牲性能。

高手的思路是:先分析场景痛点,再选方案,而不是一上来就加锁。

最后留个问题:

为什么秒杀库存扣减不用乐观锁,甚至不用分布式锁?

如果你还没想明白,不妨回到上面的 SQL 细细琢磨。
提示:答案藏在 MySQL 行锁 和 WHERE 条件 里,

并不是不需要加锁,而是把加锁的操作交给了DB。

**-**05-

粉丝福利

点点关注,送你 SQL Server 性能调优实战,如果你正在优化 SQL,又或者刚准备调优性能。可以仔细阅读一下,或许对你有所帮助!

image.png

image.png