什么是乐观锁?原理、实现方式与实战详解

在高并发系统中,如何保证数据一致性,又尽量提升系统性能,是一个绕不开的话题。乐观锁正是在这种背景下被广泛使用的一种并发控制机制。本文将从概念、原理、实现方式、应用场景和实战案例等方面,带你系统理解什么是乐观锁。


文章目录

一、什么是乐观锁?

1. 乐观锁的定义

乐观锁(Optimistic Lock),是一种对并发冲突持"乐观态度"的锁机制。

它的核心思想是:

认为并发冲突发生的概率较低,操作时不加锁,提交时再校验。

如果发现数据被修改过,就重试或失败处理。


2. 通俗理解

乐观锁可以理解为:

  • "先干活,后检查"
  • "出问题再重来"

就像写文档时:

先编辑,保存时提示冲突再处理。

不会一开始就锁住文件。


二、乐观锁的工作原理

乐观锁的一般执行流程:

  1. 读取数据
  2. 记录版本号/状态值
  3. 修改数据
  4. 提交时校验版本
  5. 校验成功则更新,否则失败重试

示意流程:

本质上:

通过校验机制,而不是阻塞机制保证一致性。


三、乐观锁的主要实现方式

1. 基于版本号(Version)实现

这是最常见的乐观锁方案。

数据库表结构示例:

sql 复制代码
ALTER TABLE product ADD version INT;

更新时校验版本:

sql 复制代码
UPDATE product
SET stock = stock - 1, version = version + 1
WHERE id = 1 AND version = 3;

特点:

  • 只有版本匹配才会更新成功
  • 否则返回 0 行受影响
  • 调用方决定是否重试

2. 基于时间戳实现

使用时间字段判断数据是否被修改。

示例:

sql 复制代码
WHERE id = 1 AND update_time = '2026-02-14 10:00:00'

本质与版本号类似,但精度依赖时间戳。


3. CAS(Compare And Swap)机制

在 Java 并发包中,大量使用 CAS 实现乐观锁。

示例:

java 复制代码
AtomicInteger count = new AtomicInteger(0);
count.compareAndSet(0, 1);

CAS 逻辑:

如果当前值等于期望值,则更新,否则失败。


四、乐观锁 vs 悲观锁

理解乐观锁,必须和悲观锁对比来看。

对比维度 乐观锁 悲观锁
并发态度 乐观 悲观
是否加锁
冲突处理 重试 阻塞
性能 稳定
适合场景 读多写少 写多冲突多

一句话总结:

冲突少用乐观锁,冲突多用悲观锁。


五、乐观锁的典型使用场景

1. 读多写少系统

例如:

  • 商品信息查询
  • 配置中心
  • 用户资料

读远大于写,冲突概率低。


2. 高并发但低冲突场景

例如:

  • 抢优惠券
  • 抽奖系统
  • 秒杀预减库存

适合乐观锁提升吞吐量。


3. 分布式系统

在微服务环境中,加锁成本高,乐观锁更常用。


六、实战案例:库存扣减

1. 不安全写法

java 复制代码
stock = stock - 1;

可能导致超卖。


2. 基于版本号的乐观锁实现

sql 复制代码
UPDATE goods
SET stock = stock - 1,
    version = version + 1
WHERE id = 1 AND version = #{version};

Java 伪代码:

java 复制代码
while (true) {
    Goods goods = query();
    boolean success = update(goods);
    if (success) break;
}

失败则重试。


七、乐观锁的优缺点分析

优点

  • 并发性能高
  • 无阻塞
  • 吞吐量大
  • 适合分布式系统

缺点

  • 实现复杂
  • 重试成本高
  • 冲突多时性能下降
  • 可能出现 ABA 问题

八、使用乐观锁的注意事项

1. 控制重试次数

避免无限重试导致 CPU 飙高。

建议设置最大重试次数。


2. 防止 ABA 问题

ABA:值变了又变回原值。

解决方案:

  • 加版本号
  • 使用带时间戳的标记

3. 结合业务降级处理

多次失败时:

  • 返回失败
  • 排队处理
  • 转人工

避免系统雪崩。


九、面试常见问题

1. 什么是乐观锁?

答:

不加锁,通过版本校验保证一致性。


2. 乐观锁适合什么场景?

答:

读多写少、冲突少场景。


3. CAS 和乐观锁关系?

答:

CAS 是乐观锁的底层实现方式之一。


参考

Java并发常见面试题总结(中)

相关推荐
像风一样的男人@1 小时前
python --打包pyd或so文件
开发语言·python
愚者游世1 小时前
long long各版本异同
开发语言·c++·程序人生·职场和发展
小光学长1 小时前
基于ssm的校园约自习网站23i21xj4(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·数据库·spring
人道领域1 小时前
Spring拦截器原理与实战详解
java·运维·服务器
茶杯梦轩1 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端
振鹏Dong2 小时前
ReActAgent 源码深度拆解:从调用入口到 ReAct-Loop,读懂智能体 “推理 - 行动” 范式
java·人工智能·spring·ai
QQ 31316378902 小时前
文华财经期货指标公式大全精品套装无未来
java
低代码布道师2 小时前
Next.js 16 全栈实战(三):数据库建模与动态菜单实现
开发语言·javascript·数据库
MediaTea2 小时前
Python:生成器对象的扩展接口
开发语言·网络·python