🎯 全网最全!Spring Boot 分布式锁从入门到实战(5 种方案 + 秒杀场景 + 完整源码)

一个通俗易懂的 Spring Boot 分布式锁学习项目,5 种锁方案、真实业务场景、1400+ 行详细文档,手把手教你从理论到生产实践!


📢 写在前面

作为一名 Java 开发者,你是否遇到过这些问题:

😱 真实踩坑场景

场景 1:秒杀库存扣成负数

库存 100 件,1000 人同时抢
结果:卖出 150 件,库存变成 -50
老板:谁干的?!

场景 2:定时任务重复执行

3 台服务器同时执行"每日结算"
结果:用户被扣了 3 次钱
客服:电话被打爆了

场景 3:订单重复提交

用户手抖点了 3 次"支付"
结果:同一笔订单扣了 3 次款
财务:账对不上了

根本原因:单机锁(synchronized)在分布式环境下失效了!


🌟 项目亮点

亮点 说明
5 种锁方案 Redis、Redisson、Redlock、Zookeeper、数据库锁全覆盖
通俗易懂 生活化比喻(厕所门锁、商场储物柜),小白也能懂
真实场景 秒杀扣库存、防重复提交、定时任务防重
最佳实践 工业级四层防护机制,可直接用于生产
代码简洁 不使用 Lambda,步骤清晰,注释详细
完整文档 1400+ 行 README,CAP/BASE 理论详细讲解

🚀 快速开始

环境要求

  • JDK 8+
  • MySQL 8.0+
  • Redis 5.0+

一键启动

# 1. 克隆项目
git clone https://gitcode.com/lipansfj/distributed-lock-learning.git

# 2. 修改数据库配置(application.yml)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/distributed_lock_db
    username: root
    password: your_password

# 3. 运行项目
mvn clean spring-boot:run

# 4. 访问 API 文档
# http://localhost:8080/doc.html

📚 项目全景图

核心模块

distributed-lock-learning/
├── 5 种锁方案实现
│   ├── SimpleLockService      # Redis 基础锁(学习原理)
│   ├── RedissonLockService    # Redisson 看门狗锁(生产推荐)
│   ├── RedlockService         # Redlock 算法(高可用)
│   ├── ZkLockService          # Zookeeper 锁(强一致性)
│   └── DatabaseLockService    # 数据库锁(简单场景)
│
├── 3 个业务场景
│   ├── SeckillController      # 秒杀扣库存
│   ├── OrderController        # 防重复提交
│   └── LockDemoController     # 锁演示接口
│
├── 混合策略
│   └── HybridLockService      # 根据优先级选锁
│
└── 完整文档
    └── README.md              # 1400+ 行详细教程

💡 核心理论(一句话记住)

CAP 理论

口诀:分布式系统,P 必须选,C 和 A 只能选一个

生活化比喻:就像"快、好、省"只能三选二

场景演示

假设:北京和上海两个银行节点,网络断了

选择 CP(一致性 + 分区容错):
→ 暂停服务,保证数据一致
→ ✅ 数据正确  ❌ 不可用
→ 适用:银行转账、库存扣减

选择 AP(可用性 + 分区容错):
→ 继续服务,允许短暂不一致
→ ✅ 可用  ⚠️ 数据可能不一致
→ 适用:微信点赞、Redis 缓存

BASE 理论

口诀:基本可用,允许中间状态,最终会一致

秒杀订单案例

T=0ms:  用户点击"立即购买"
T=10ms: 订单创建,返回"下单成功" ✅ (基本可用)
T=11ms: 订单状态: PROCESSING ⚠️ (软状态)
T=2s:   库存扣减完成,状态: SUCCESS ✅ (最终一致)

用户感知:立即看到成功(体验好)
后台处理:异步扣库存(高性能)

🛠️ 5 种分布式锁方案对比

方案 可靠性 性能 复杂度 适用场景
Redis 基础锁 ⭐⭐ ⭐⭐⭐⭐⭐ 学习原理
Redisson 看门狗 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 生产推荐
Redlock ⭐⭐⭐⭐⭐ ⭐⭐⭐ 高可用要求
Zookeeper ⭐⭐⭐⭐⭐ ⭐⭐ 强一致性
数据库锁 ⭐⭐⭐⭐ 低并发

💻 核心代码实战

方案 1:Redis 基础锁(理解原理)

核心方法

Boolean locked = redisTemplate.opsForValue()
    .setIfAbsent(lockKey, requestId, 10, TimeUnit.SECONDS);

完整实现(简单易懂):

// 步骤1:尝试获取锁
String requestId = simpleLockService.tryLock(lockKey, 10);

if (requestId == null) {
    return false; // 获取锁失败
}

try {
    // 步骤2:执行业务逻辑
    doBusiness();
    
} finally {
    // 步骤3:释放锁(必须验证拥有者)
    simpleLockService.releaseLock(lockKey, requestId);
}

⚠️ 常见错误

// ❌ 错误1:不设置过期时间 → 死锁
redisTemplate.opsForValue().setIfAbsent(key, value);

// ❌ 错误2:分开设置值和过期时间 → 非原子操作
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, 10, TimeUnit.SECONDS);

// ❌ 错误3:不验证锁的拥有者 → 误删别人的锁
redisTemplate.delete(key);

方案 2:Redisson 看门狗锁(生产推荐)⭐

核心问题:锁设置 10 秒过期,但业务需要执行 20 秒,怎么办?

传统锁的问题

T=0s:   线程A获取锁,设置10秒过期
T=10s:  ⚠️ 锁自动释放,线程B也能获取锁
T=10-20s: 线程A和B同时执行 ❌ 并发安全问题!

Redisson 看门狗解决方案

T=0s:   线程A获取锁,看门狗启动(默认30秒)
T=10s:  看门狗检查 → 还持有锁 → 自动续期30秒
T=20s:  看门狗检查 → 还持有锁 → 再次续期30秒
T=50s:  业务完成,调用unlock(),停止看门狗

代码实现(简单 4 步):

// 步骤1:先获取锁
boolean locked = redissonLockService.tryLock(lockKey, 3, 10);

if (!locked) {
    // 获取锁失败,立即返回
    return ApiResponse.fail("获取锁超时");
}

try {
    // 步骤2:执行业务逻辑
    log.info("获取锁成功,开始执行业务逻辑...");
    
    // 模拟业务处理(比如查询数据库、调用接口等)
    Thread.sleep(2000);
    
    // 步骤3:返回业务结果
    result.put("success", true);
    result.put("message", "业务执行成功");
    
} catch (InterruptedException e) {
    // 异常处理
    result.put("success", false);
    result.put("message", "业务执行被中断");
    
} finally {
    // 步骤4:释放锁(无论成功还是失败都要释放)
    redissonLockService.unlock(lockKey);
    log.info("锁已释放");
}

优势

  • ✅ 自动看门狗续期,不会提前过期
  • ✅ 支持可重入锁(同一线程可多次获取)
  • ✅ 一行代码搞定,代码简洁

方案 3:混合锁策略(智能选择)

根据业务优先级自动选择锁

// 高优先级:使用 Zookeeper(强一致性)
hybridLockService.executeWithPriority(
    LockPriority.HIGH, 
    lockKey, 
    () -> criticalBusiness()
);

// 中优先级:使用 Redlock(平衡性能和可靠性)
hybridLockService.executeWithPriority(
    LockPriority.MEDIUM, 
    lockKey, 
    () -> normalBusiness()
);

// 低优先级:使用 Redisson(高性能)
hybridLockService.executeWithPriority(
    LockPriority.LOW, 
    lockKey, 
    () -> commonBusiness()
);

🔥 真实业务场景

场景 1:秒杀扣库存(四层防护)

@Transactional
public Result seckill(Long productId, Long userId) {
    RLock lock = redisson.getLock("seckill:" + productId);
    
    try {
        // 第1层:Redis 分布式锁(拦截 99% 并发)
        boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
        if (!locked) {
            return Result.fail("系统繁忙");
        }
        
        // 第2层:检查库存/业务规则
        Stock stock = stockMapper.selectById(productId);
        if (stock.getCount() <= 0) {
            return Result.fail("库存不足");
        }
        
        // 第3层:数据库乐观锁(版本号控制)
        int affected = stockMapper.decreaseWithVersion(productId);
        if (affected == 0) {
            return Result.fail("库存不足");
        }
        
        // 第4层:数据库唯一约束(防止重复购买)
        try {
            orderMapper.insert(productId, userId);
        } catch (DuplicateKeyException e) {
            return Result.fail("请勿重复购买");
        }
        
        return Result.success();
        
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

四层防护机制

  1. Redis 锁:拦截 99% 并发请求
  2. 库存检查:快速失败,减少数据库压力
  3. 乐观锁:版本号控制,防止并发更新
  4. 唯一约束:数据库兜底,防止重复购买

场景 2:防重复提交

@PostMapping("/create")
public Result createOrder(@RequestBody OrderRequest request) {
    // 使用用户ID + 商品ID作为锁
    String lockKey = "order:create:" + request.getUserId() 
                   + ":" + request.getProductId();
    
    boolean locked = redissonLockService.tryLock(lockKey, 3, 10);
    if (!locked) {
        return Result.fail("请勿重复提交");
    }
    
    try {
        // 创建订单
        orderService.create(request);
        return Result.success("订单创建成功");
        
    } finally {
        redissonLockService.unlock(lockKey);
    }
}

📊 性能对比数据

方案 RT(响应时间) QPS 性能下降
Redis 普通锁 1-5ms 8000+ -
Redisson 锁 1-5ms 8000+ -
Redlock 5-10ms 2000-3000 ↓ 70%
Zookeeper 10-50ms 1000-2000 ↓ 80%
数据库锁 100-500ms < 1000 ↓ 90%

选型建议

  • 90% 的场景:Redisson + 数据库兜底
  • 金融级场景:Zookeeper 或 etcd
  • 低并发场景:数据库乐观锁即可
  • 永远不要:只依赖一层防护

🎯 适用人群

人群 能获得什么
🎓 初学者 系统学习分布式锁,从理论到实践
💼 中级开发 应对面试,掌握生产级方案
👨‍ 高级开发 参考最佳实践和架构设计
📚 培训讲师 完整的教学材料和案例

📦 项目结构

distributed-lock-learning/
├── src/main/java/
│   ├── config/              # 配置类
│   │   ├── RedissonConfig.java      # Redisson 配置
│   │   ├── ZookeeperConfig.java     # Zookeeper 配置
│   │   └── Knife4jConfig.java       # API 文档配置
│   │
│   ├── controller/          # REST API
│   │   ├── LockDemoController.java  # 锁演示接口
│   │   ├── SeckillController.java   # 秒杀接口
│   │   └── OrderController.java     # 订单接口
│   │
│   ├── service/             # 业务逻辑
│   │   ├── SimpleLockService.java   # Redis 基础锁
│   │   ├── RedissonLockService.java # Redisson 看门狗锁
│   │   ├── RedlockService.java      # Redlock 算法
│   │   ├── ZkLockService.java       # Zookeeper 锁
│   │   ├── DatabaseLockService.java # 数据库锁
│   │   └── HybridLockService.java   # 混合策略
│   │
│   ├── entity/              # 实体类
│   │   ├── Stock.java               # 库存表
│   │   ├── Orders.java              # 订单表
│   │   └── DistributedLock.java     # 锁记录表
│   │
│   ├── mapper/              # MyBatis Mapper
│   ├── dto/                 # 数据传输对象
│   └── common/              # 通用工具类
│
├── src/main/resources/
│   ├── application.yml      # 配置文件
│   └── schema.sql           # 数据库建表脚本
│
└── README.md                # 1400+ 行完整文档

学习路线图

第一阶段:为什么需要分布式锁?
  └─ 单机锁的局限性(synchronized 失效)

第二阶段:理论基础
  └─ CAP 理论 + BASE 理论

第三阶段:基础实现
  └─ Redis setIfAbsent() 原子操作

第四阶段:生产级方案
  └─ Redisson 看门狗锁(自动续期)

第五阶段:高级方案
  ├─ Redlock(多节点高可用)
  ├─ Zookeeper(强一致性)
  └─ 数据库锁(简单场景)

第六阶段:最佳实践
  └─ 多层防护机制(四层防护)

📝 常见问题

Q1: 为什么不直接用 synchronized?

A: synchronized 是 JVM 级别的锁,只能在单个进程中生效。分布式环境下有多个服务器,synchronized 无法跨进程互斥。

生活化比喻

  • synchronized = 家里厕所的门锁(只有自己家人能用)
  • 分布式锁 = 商场公共厕所的门锁(所有人都能看到是否有人)

Q2: Redis 锁可靠吗?会不会丢锁?

A: Redis 锁在主从切换时可能丢锁,但概率较低(约 1-5%/年)。对于 90% 的业务场景,Redis 锁 + 数据库兜底已经足够可靠。

建议

  • 非关键业务:Redis 锁即可
  • 关键业务:Redis 锁 + 数据库乐观锁 + 唯一约束(多层防护)
  • 金融级业务:Zookeeper

Q3: 锁的超时时间应该设置多久?

A: 根据业务耗时的 1.5-2 倍 设置。

示例

  • 业务平均耗时 3 秒 → 锁超时设置为 5-6 秒
  • 业务平均耗时 100ms → 锁超时设置为 150-200ms

注意:如果使用 Redisson,可以启用看门狗机制,自动续期锁。


Q4: 项目可以直接用于生产吗?

A: 可以!项目包含了生产级的多层防护方案,Redisson 看门狗锁已在多个实际项目中使用。


🚀 如何获取

项目地址:https://gitcode.com/lipansfj/distributed-lock-learning.git

# 克隆项目
git clone https://gitcode.com/lipansfj/distributed-lock-learning.git

# 进入项目目录
cd distributed-lock-learning

# 运行项目
mvn clean spring-boot:run

# 访问 API 文档
# http://localhost:8080/doc.html

⭐ 如果觉得有帮助

如果这个项目对你有帮助,请:

  1. 给项目一个 Star
  2. 分享给需要的朋友 📢
  3. 应用到实际项目中 💪

你的支持是我持续更新的动力!🙏


📮 联系方式

  • 项目地址:https://gitcode.com/lipansfj/distributed-lock-learning.git
  • 问题反馈:欢迎提 Issue 或 PR
  • 技术交流:欢迎 Fork 和 Star

💡 温馨提示:如果觉得这篇文章对你有帮助,请点赞、收藏、转发,让更多人看到!

关注我,获取更多 Java 实战项目和经验分享!🚀

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐