记录一次redis分布式锁的坑
redis分布式锁的实现方式是:
lock(){ sync(this){
//无法获取自旋 setnx(key,UUID) setex(60s) return UUID } } unlock(key,value){ sync(this){ if(get(key) == UUID){ del(key) } } }
备注:由于redisTemplate版本问题,没有setnxex的原子操作,而且unlock也有两步操作,为了保证单机原子性,加上了sync对象锁,并且lock和unlock锁同一个对象。
看山去一切都很美,但是运行起来发现问题了:并发量一上来,分布式锁并不会正常解锁,而是每次都要等60s自动过期后才能解锁。。。。
仔细分析了下问题原因:
线程A先进入lock方法,获取sync对象锁,获取到分布式锁,释放sync对象锁
线程A执行业务代码
线程B进入lock方法,获取sync对象锁,但无法获取分布式锁,自旋等待
线程A进入unlock方法,尝试获取sync对象锁,但此时sync对象锁被线程B占用,需要等待线程B释放sync对象锁
这时线程A B有死锁,需要等待其中一个锁自动解锁,就是分布式锁的60s,这就解释了为什么每次都要等60s!!!!
而且这种方法还只能在单机保证线程安全,想要实现一个优秀的分布式锁,还必须要满足分布式原子性!
标签:
redis
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架