redis分布式锁的复杂实现
一,业务场景,秒杀系统
1,实现分布式锁
2,不能超卖
二,实现逻辑
1,synchronized,在抢购方法上加同步锁synchronized,弊端:只使用单机环境;很慢。只有所有逻辑执行完,下个人才能购买,把东西卖完耗时长
2,redis锁,在方法内部对商品加锁,解锁成功,继续执行购买操作,最后解锁。但是productId相同,不还是只用一个人能执行业务逻辑,其他用户只有等待吗?(暂不考虑为什么这样快)
三,加锁实现
3.1)如下,直接加锁,会导致两个问题
1,可能死锁,服务挂了,finally也没法释放
2,
3.2)针对上面的问题,直接加个过期时间不就行了,实际上是这样实现的,如下图
那中间这一坨代码实现什么功能?
1,设置过期时间,过期了,其他线程立即加锁执行购买
2,?
逻辑
1,线程1,加锁成功,返回true,下面代码不执行。这时候服务挂了,不还是死锁吗,没有过期时间?
假设起始时间为1000ms,即线程1进来时间
key:100
value:1000+100ms = 1100
线程1("100", "1100")
2,线程2,过了200ms,如果另外一个线程过来,当前时间1200
线程2("100", " 1300")1000+200+100 = 1300
currentValue:1100
当前系统时间:1000+200 = 1200 1100<1200,说明线程1过期了。
这时候业务可能没执行完(怎么办),且锁还没释放,在此获取时get/getAntSet时,发现锁过期了,才删除原来的锁,业务没执行完怎么办?锁已释放,是不是其他用户可以购买?是不是可以把值往大了设,确保业务逻辑执行完,finally释放锁(弊端:死锁了怎么办)(先不管)
3,如果线程1没过期,线程二返回false,加锁失败,不会执行购买逻辑,返回排队中...........
4,线程1过期了,线程2执行getAntSet,注意这里只有一个线程能执行成功(可能同时进来两个线程都执行到这里)
oldValue:1100
当前key value("100", "1300")
5,比较老值和当前值
老值:1100
currentValue:1100
相同,返回true,线程1失效时,线程2加锁成功(如果线程1逻辑没执行完,线程2也去执行业务逻辑,会不会导致超卖?)
6,然后呢,上面这些说明什么问题
实现了,如果前面线程过期,后面线程可以,立即加锁执行购买行为
然后呢,主要说明的是这种场景
线程1持有锁,并发情况下,线程2,线程3同时进入加锁方法,且value相同
线程1("100", "1100")
线程2,线程3("100", "1300")
如果当前时间1200,线程1过期,线程2设置了当前key value("100", "1300")
老值:1100
currentValue:1100,相同加锁成功
重要的是对于线程3来说,
currentValue:1100
oldValue:应该是线程2的值,1300
明显不相同,加锁失败,等待线程2执行。
巴拉巴拉差不多说完了,现在想想中间这坨代码干啥的?
1,过期了,其他人能够立刻购买成功
2,过期了,并发时,只要一个人能购买成功。如果不加这坨呢,直接加锁时加个过期时间,不过期时,其他线程过来返回false,有啥问题吗,又绕回去了。
想不通?
其他实现逻辑
1,判断是否被锁 isLock
2,是,不执行
3,否,加锁
4,释放锁
加锁方法返回Boolean,具体实现如下
redis分布式锁的复杂实现相关推荐
- redis分布式锁 在集群模式下如何实现_收藏慢慢看系列:简洁实用的Redis分布式锁用法...
在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2. ...
- 快来学习Redis 分布式锁的背后原理
以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这 ...
- Redis分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!
点击关注公众号,Java干货及时送达 来源:juejin.cn/post/6854573212831842311 基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本篇文章主要是基于我们实际项目 ...
- Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本 ...
- 秒杀商品超卖事故:Redis分布式锁请慎用!
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浪漫先生 来源:juejin.im/post/6854573 ...
- 记一次由Redis分布式锁造成的重大事故,避免以后踩坑!
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浪漫先生 juejin.im/post/5f159cd8f2 ...
- 简单介绍redis分布式锁解决表单重复提交的问题
在系统中,有些接口如果重复提交,可能会造成脏数据或者其他的严重的问题,所以我们一般会对与数据库有交互的接口进行重复处理.本文就详细的介绍一下redis分布式锁解决表单重复提交,感兴趣的可以了解一下 假 ...
- Redis 分布式锁没这么简单,网上大多数都有 bug
Redis 分布式锁这个话题似乎烂大街了,不管你是面试还是工作,随处可见,「码哥」为啥还写? 因为看过很多文章没有将分布式锁的各种问题讲明白,所以准备写一篇,也当做自己的学习总结. 在进入正文之前,我 ...
- 深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!
阅读本文大约需要 20 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊,关于 Redis 分布式锁的「安全性」问题. Redis 分布式锁的话题,很多文章已经写烂了 ...
- SpringBoot + Redis 分布式锁:模拟抢单
作者:神牛003 cnblogs.com/wangrudong003/p/10627539.html 本篇内容主要讲解的是redis分布式锁,这个在各大厂面试几乎都是必备的,下面结合模拟抢单的场景来使 ...
最新文章
- could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR 错误的解决办法
- pbp 读取 mysql数据_SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)...
- 基于python的FFT频率和振幅处理
- 一些常用的系统存储过程
- 我的设计模型之适配器模式
- Helm 3 完整教程(六):在模板中使用 Helm 函数
- Elasticsearch的javaAPI之facet,count,delete by query
- 统计python文件中的代码,注释,空白对应的行数
- html 强制占据一行,html – 如何强制内联div保持在同一行?
- Docker从理论到实践(二)------配置Docker镜像源加速器(部分使用效果已不太理想)
- 计算机ppt咋弄,ppt打不开怎么办?教您详细解决方法
- 计算机无法进bios,电脑进入不了bios界面怎么办_win7无法进入bios界面如何解决-系统城...
- 个人申请微信公众号步骤(含截图)
- 当你的Stream遇上Lambda就爱上了,超级无敌酷酷 - 第418篇
- 四旋翼无人机——导航、制导与控制的概念
- csp试题2:二十四点
- Socket error Event: 32 Error: 10053
- SecureCRTSecureFX(一):SecureCRT的介绍与下载安装
- Android项目源码分享
- 【玩转嵌入式屏幕显示】(四)TFT-LCD屏幕显示英文字符(ASCII)和字符串
热门文章
- Java第十二次作业:继承与抽象类解决工人与学生的问题,抽象类实例。抽象类作用——为多态创造了可能。抽象类的作用总结...
- iOS:NSDate的主要几种时间形式
- 改进:js修改iOS微信浏览器的title
- mycelipse中关于编码的配置
- 陆兆禧:此时此刻,非我莫属!
- c++学习笔记---指针
- C++实现获取汉字拼音首字母
- android按钮点击后闪退_iphone闪退是什么原因?
- Linux内核线程kernel thread详解--Linux进程的管理与调度(十)
- linux网络子系统分析(四)—— INET连接建立API分析之connect/accept