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

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


文章目录

一、什么是乐观锁?

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 小时前
带您看懂字节码指令(一):一帧里有什么
java·后端·ai编程
nice_lcj5203 小时前
【从零理解 Spring AI · 14】RAG 的四个环节:加载、切分、向量化、检索
java·spring boot·embedding·向量数据库·rag·spring ai·ai应用开发
SomeOtherTime3 小时前
Rust所有权(AI回答)
开发语言·后端·rust
Easyhood3 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青4 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
学长毕设4 小时前
基于springboot科创竞赛信息平台-附源码
java·spring boot·后端
聪明的笨猪猪5 小时前
Java 工程案例:AI 生成 @Async 异步线程池踩坑
java·经验分享·面试·ai编程
学长毕设5 小时前
基于SpringBoot公务员考试交流平台-附源码
java·spring boot·后端
SL_staff8 小时前
私有化低代码:面向强监管行业的可控数字化实践
java·低代码
饮水桶_T8 小时前
JAVA IO流笔记
开发语言·数据结构·算法