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

使用Redis如何实现分布式锁?(超卖)

 分布式锁概念


在多线程环境下,为了保证数据的线程安全,锁保证同一时刻,只有一个可以访问和更新共享数据。在单机系统我们可以使用 synchronized 锁、Lock 锁保证线程安全。

synchronized 锁是 Java 提供的一种内置锁,在单个 JVM 进程中提供线程之间的锁定机制,控制多线程并发。只适用于单机环境下的并发控制。

想要在多个节点中提供锁定,在分布式系统并发控制共享资源,确保同一时刻只有一个访问可以调用,避免多个调用者竞争调用和数据不一致问题,保证数据的一致性,就需要分布式锁。

分布式锁:控制分布式系统不同进程访问共享资源的一种锁的机制。不同进程之间调用需要保持互斥性,任意时刻,只有一个客户端能持有锁。

共享资源包含:

数据库
文件硬盘
共享内存
分布式锁特性:

互斥性:锁只能被持有的客户端删除,不能被其他客户端删除
锁超时释放:持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁
可重入性:一个线程如果获取了锁之后,可以再次对其请求加锁。
高性能和高可用:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效
安全性:锁只能被持有的客户端删除,不能被其他客户端删除

创建锁

使用Redis实现分布式锁可以通过setnx(set if not exists)命令实现,但当我们使用setnx创建键值成功时,则表中加锁成功,否则代码加锁失败,实现示例如下:

127.0.0.1:6379> setnx lock true
(integer) 1#创建锁成功
#逻辑业务处理..

 当我们重复加锁时,只有第一次会加锁成功

127.8..1:6379> setnx lock true # 第一次加锁
(integer) 1
127.8.8.1:6379> setnx lock true # 第二次加锁
(integer) 0

 从上述命令可以看出,我们可以看执行结果返回是不是1,就可以看出是否加锁成功

释放分布式锁 

127.0.0.1:6379> de1 lock
(integer) 1 #释放锁

 然而,如果使用 setnx ock true 实现分布式锁会存在死锁问题,以为 setnx 如未设置过期时间,锁忘记删了或加锁线程宕机都会导致死锁,也就是分布式锁一直被占用的情况

解决死锁问题

死锁问题可以通过设置超时时间来解决,如果超过了超时时间,分布锁会自动释放,这样就不会存在死锁问题了也就是 setnx和 expire 配合使用,在 Redis 2.6.12 版本之后,新增了一个强大的功能,我们可以使用一个原子操作也就是一条命令来执行 setnx 和expire 操作了,实现示例如下:
 

127.0.0.1:6379> set lock true ex 3 nx
OK #创建锁成功
127...1:6379> set lock true ex 3 nx
(ni1) #在锁被占用的时候,企图获取锁失败

其中ex为设置超时时间, nx 为元素非空判断,用来判断是否能正常使用锁的。
因此,我们在 Redis 中实现分布式锁最直接的方案就是使用 set key value ex timeout nx 的方式来实现

超卖问题

这是因为在并发环境下,多个线程下单操作,前面的线程还未更新库存,后面的线程已经请求进来,并获取到了未更新的库存,后续扣减库存都不是扣减最近的库存。线程越多,扣减的库存越少。这就是在高并发场景下发生的超卖问题。

很明显,上述问题是出现了线程安全的问题,我们首先能想到的肯定是给它加 synchronized 锁。

是的,没问题,但是我们知道,synchronized 锁是属于JVM 级别的,也就是我们所谓的“单机锁”,如果是多机部署的环境中,还能保证数据的一致性吗?

答案肯定是不能的。这个时候,就需要用到了我们 Redis 分布式锁

用 Redis 实现分布式锁的几种方案,都是用 SETNX 命令(设置 key 等于某 value)。只是高阶方案传的参数个数不一样,以及考虑了异常情况

 

相关文章:

  • JVM的各种细节
  • android 新闻客户端和springboot后台开发(一)
  • 如何处理PHP中的日期和时间问题
  • Node.js REPL 深入解析
  • OTSU算法(大津算法)
  • DeepSeek技术解析:MoE架构实现与代码实战
  • Python高级算法与数据结构优化实战
  • 网络质量分析(NQA) 技术详解:原理、应用与配置实践
  • 51c大模型~合集7
  • 数据库管理-第302期 国产类RAC架构数据库网络连接方式(20250314)
  • 揭秘AI:机器学习与深度学习的奥秘
  • Unity Webgl在编辑器中报错:Cannot connect to destination host
  • Audacity的安装和使用
  • ToB公司找客户专用|大数据获客系统
  • STM32F407 IIC通信
  • 书籍品读:我的世界(陈州)
  • Linux(2025.3.14)
  • iOS底层原理系列04-并发编程
  • 【电流源和电压源串联和并联】2022-10-19
  • Ubuntu 服务器安装 Python 环境 的详细指南
  • 中国纪检监察刊文:力戒形式主义官僚主义关键是要坚持实事求是
  • 六省会共建交通枢纽集群,中部离经济“第五极”有多远?
  • 视频丨中国海警成功救助8名外籍遇险渔民,韩方向中方致谢
  • 张广智︱“编年事辑”:打开学人心路历程的窗户
  • 中国乒协坚决抵制恶意造谣,刘国梁21日将前往多哈参加国际乒联会议
  • 国台办:民进党当局刻意刁难大陆配偶,这是不折不扣的政治迫害