沉默的背影 X-Pacific

keep learning

记录一次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!!!!

而且这种方法还只能在单机保证线程安全,想要实现一个优秀的分布式锁,还必须要满足分布式原子性!

posted @ 2022-10-29 23:01  乂墨EMO  阅读(65)  评论(0编辑  收藏  举报