当前位置: 首页 > news >正文

redis和数据库实现分布式锁

目录

  • 一、为什么需要分布式锁
    • 1. 什么是锁
    • 2. 单机锁为什么失效
  • 二、分布式锁是什么
  • 三、分布式锁需要满足什么条件
    • 1. 互斥性
    • 2. 可重入
    • 3. 防死锁
    • 4. 高可用
  • 四、Redis实现分布式锁
    • 1. 原理
    • 2. Spring Boot实现
      • 加锁
      • 释放锁
    • 3. Redisson实现
  • 五、数据库唯一索引实现分布式锁
    • 1. 建表
    • 2. 获取锁
    • 3. 原理
    • 4. 缺点
  • 六、数据库乐观锁(版本号)
    • 1. 表结构
    • 2. 查询
    • 3. 更新
    • 4. 原理
    • 5. MyBatis Plus实现
  • 七、数据库悲观锁
    • 1. 获取锁
    • 2. 原理
    • 3. 缺点
  • 八、ZooKeeper实现分布式锁
  • 九、各种方案对比
  • 十、单机环境如何实现锁
    • 1. synchronized
    • 2. ReentrantLock
    • 3. ReadWriteLock
  • 总结

一、为什么需要分布式锁

1. 什么是锁

锁(Lock)的本质是:

保证同一时刻只有一个线程(或一个进程)能够执行某段代码。

例如:

publicvoiddeductStock(){stock--;}

假设库存为 1:

  • 用户A购买
  • 用户B购买

两个线程同时执行:

stock--;

结果可能变成:

库存:-1

这就是典型的并发问题。

因此需要锁来保证:

synchronized(lock){stock--;}

同一时刻只能有一个线程进入。


2. 单机锁为什么失效

在单体应用中:

JVM ┌─────────────────┐ │ Thread-1 │ │ Thread-2 │ │ synchronized │ └─────────────────┘

synchronizedReentrantLock都能正常工作。

但是微服务部署后:

Nginx / \ Service-A Service-B JVM1 JVM2

用户请求可能进入:

请求1 -> JVM1 请求2 -> JVM2

此时:

synchronized(lock)

只锁住当前 JVM。

因为:

JVM1 不知道 JVM2 的锁状态 JVM2 不知道 JVM1 的锁状态

于是两个服务同时执行。

这就是:

本地锁失效问题

因此需要:

所有节点共享同一把锁

这就是分布式锁。


二、分布式锁是什么

定义:

分布式系统中多个节点共同竞争同一个共享资源时,用来保证同一时刻只有一个节点执行操作的机制。

例如:

秒杀活动 定时任务 订单创建 库存扣减 退款操作

都可能需要分布式锁。


三、分布式锁需要满足什么条件

一个合格的分布式锁通常需要满足:

1. 互斥性

同一时间只能一个客户端获得锁

2. 可重入

例如:

methodA()->methodB()

methodA已经获得锁。

methodB再次加锁:

lock.lock();

不能死锁。


3. 防死锁

持有锁的服务挂掉:

JVM Crash

锁必须自动释放。

通常依赖:

TTL过期时间

4. 高可用

Redis挂了:

锁全部失效

需要主从、哨兵或集群保障。


四、Redis实现分布式锁

这是目前最常见的方案。


1. 原理

Redis提供:

SET key value NX EX 30

含义:

NX:不存在才创建 EX:30秒过期

执行成功:

OK

说明获得锁。

执行失败:

null

说明锁已被占用。


2. Spring Boot实现

加锁

@AutowiredprivateStringRedisTemplateredisTemplate;publicbooleantryLock(Stringkey){returnBoolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key,UUID.randomUUID().toString(),30,TimeUnit.SECONDS));}

底层执行:

SET lock:order uuid NX EX 30

释放锁

错误写法:

redisTemplate.delete(key);

问题:

线程A锁超时 线程B获得锁 线程A执行delete 把线程B的锁删了

正确做法:

Stringlua="if redis.call('get',KEYS[1])==ARGV[1] then "+" return redis.call('del',KEYS[1]) "+"else return 0 end";redisTemplate.execute(newDefaultRedisScript<>(lua,Long.class),Collections.singletonList(key),uuid);

保证:

谁加锁 谁解锁

3. Redisson实现

实际项目更推荐。

引入:

<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency>

获取锁:

RLocklock=redissonClient.getLock("orderLock");try{lock.lock();createOrder();}finally{lock.unlock();}

优点:

自动续期 可重入 看门狗机制 高可靠

面试中一般回答:

生产环境推荐 Redisson。


五、数据库唯一索引实现分布式锁

这是最简单的方案之一。


1. 建表

CREATETABLEdistributed_lock(lock_nameVARCHAR(100)PRIMARYKEY,create_timeDATETIME);

2. 获取锁

try{lockMapper.insert(lockName);returntrue;}catch(DuplicateKeyExceptione){returnfalse;}

对应SQL:

INSERTINTOdistributed_lockVALUES('ORDER_LOCK',NOW());

3. 原理

假设:

JVM1 插入成功 JVM2 插入同样主键

数据库保证:

主键唯一

第二次插入失败。

因此:

只有一个服务获得锁

4. 缺点

数据库压力大:

频繁insert 频繁delete

性能远低于Redis。


六、数据库乐观锁(版本号)

严格来说:

它不是传统意义上的分布式锁

但经常用于解决并发问题。


1. 表结构

CREATETABLEstock(idBIGINT,stockINT,versionINT);

数据:

stock = 100 version = 1

2. 查询

SELECTstock,versionFROMstockWHEREid=1;

得到:

stock=100 version=1

3. 更新

UPDATEstockSETstock=stock-1,version=version+1WHEREid=1ANDversion=1;

4. 原理

线程A:

version=1

线程B:

version=1

线程A先更新:

version=2

线程B再更新:

WHEREversion=1

匹配不到。

更新失败:

update count = 0

然后重试。


5. MyBatis Plus实现

实体:

@VersionprivateIntegerversion;

配置:

@BeanpublicMybatisPlusInterceptorinterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());returninterceptor;}

更新时自动带:

version=oldVersion

条件。


七、数据库悲观锁

利用数据库行锁。


1. 获取锁

SELECT*FROMstockWHEREid=1FORUPDATE;

2. 原理

事务提交前:

其他事务无法修改这条记录

例如:

@TransactionalpublicvoiddeductStock(){Stockstock=stockMapper.selectForUpdate(1L);stock.setCount(stock.getCount()-1);stockMapper.update(stock);}

3. 缺点

性能较差:

锁粒度大 阻塞严重 数据库压力高

八、ZooKeeper实现分布式锁

原理:

临时顺序节点

例如:

/lock/order0001 /lock/order0002 /lock/order0003

最小节点获得锁:

order0001

删除后:

order0002

获得锁。

常见框架:

Apache Curator

优点:

一致性强 可靠

缺点:

实现复杂 性能低于Redis

九、各种方案对比

方案性能实现难度推荐程度
synchronized★★★★★简单单机
ReentrantLock★★★★★简单单机
数据库唯一索引★★简单小项目
数据库悲观锁★★简单一般
数据库乐观锁★★★★简单库存扣减
ZooKeeper★★★复杂大型系统
Redis+Lua★★★★★中等推荐
Redisson★★★★★简单生产推荐

十、单机环境如何实现锁

如果系统没有部署多个实例:

只有一个JVM

那么根本不需要分布式锁。


1. synchronized

publicsynchronizedvoidcreateOrder(){}

或者:

privatefinalObjectlock=newObject();synchronized(lock){}

特点:

JDK内置 自动释放 简单

2. ReentrantLock

privatefinalReentrantLocklock=newReentrantLock();publicvoidcreateOrder(){lock.lock();try{//业务逻辑}finally{lock.unlock();}}

优点:

可重入 可中断 支持公平锁 支持超时

3. ReadWriteLock

读多写少场景:

privateReadWriteLocklock=newReentrantReadWriteLock();

读锁:

lock.readLock().lock();

写锁:

lock.writeLock().lock();

特点:

多个读线程同时执行 写线程独占

总结

分布式锁的核心目标只有一句话:

在多个 JVM、多个服务实例同时访问同一资源时,保证同一时刻只有一个节点执行关键业务逻辑。

实际生产中:

  • 单机应用:synchronizedReentrantLock
  • 库存扣减:乐观锁(Version)
  • 中小项目:Redis + Lua
  • 企业级项目:Redisson
  • 强一致性场景:ZooKeeper

学习路径,掌握:

synchronized → ReentrantLock → Redis SET NX EX → Lua释放锁 → Redisson看门狗 → 乐观锁Version → ZooKeeper临时顺序节点

http://www.jsqmd.com/news/995593/

相关文章:

  • AI教材生成大突破!掌握这些技巧,低查重教材轻松搞定!
  • FanControl V269深度实战指南:Windows风扇智能温控与精准优化全解析
  • 2026 温州五大正规犬舍专业测评:伴西西猫舍犬舍登顶,合规繁育引领行业标杆 - 同城宠物优选基地
  • Spring Cloud LoadBalancer自定义策略全解析:从源码模仿到四种实战策略(含网关路由)
  • Better Exceptions:Python异常调试的革命性可视化解决方案
  • 【程序语言与编译】 有限自动机(DFA与NFA)
  • 手把手教你用Python脚本调试ZDT_Emm42_V5.0步进电机驱动器(Modbus-RTU协议)
  • MC9S08SH8 TPM模块深度解析:从输入捕获到PWM的实战指南
  • 保姆级教程:用STM32 HAL库驱动W25N01GV Nand Flash(含ECC校验与坏块管理思路)
  • 超星学习通自动签到终极指南:告别繁琐手动操作
  • 突破性音乐自由方案:一站式解锁全网高品质无损音乐体验
  • 终极便携C/C++开发工具包:5分钟搭建Windows专业开发环境
  • AI动态简报之算力基建篇(2026.06.11)
  • 揭秘20KV脉冲电弧:磁场下的形态之谜与直流/交流放电辨析
  • 优质后塍办理公司注销业务企业排名前十哪家强 - 品牌排行榜
  • Redis 从入门到精通:持久化RDB 与 AOF
  • 关于C语言中getchar()的详细使用
  • 别再问怎么连PLC了!手把手教你用Python+SMLP协议读写三菱FX5U数据
  • 嵌入式设计核心:外设电气规格深度解析与工程实践指南
  • 神经网络控制器的特洛伊木马攻击与防御实践
  • 用Qt和RKNN在飞凌OK3568上搞个USB摄像头实时AI识别(附完整代码和避坑指南)
  • 2026 贵阳五大犬舍专业测评:伴西西登顶,综合实力断层领先 - 同城宠物优选基地
  • 24小时健身加盟选哪个品牌更合适 - 品牌排行榜
  • 吃透二叉树与递归!60分钟掌握树结构核心+解题思路
  • 2026论文双降终极榜单:10款降AI率工具, 合规修正一路顺畅
  • 2026年绵阳高空作业车出租市场观察:服务能力与项目实绩的多维分析 - 优质品牌商家
  • C语言项目实战:用uthash给你的自定义数据结构加个‘高速缓存’
  • 3分钟完成Windows 11系统优化:免费开源工具终极指南
  • 2026 泉州犬舍 TOP5 权威榜单,伴西西断层领跑,以标准化体系重塑行业标杆 - 同城宠物优选基地
  • P89LPC912/913/914实战:SPI、模拟比较器与看门狗配置避坑指南