什么是分布式锁
通过互斥性质,来保证线程对分布式系统中共享资源的有序访问 说人话:一把锁,挨个进
分布式锁的特性
-
互斥(线程独享):即同一时刻只有一个线程能够获取锁
-
避免死锁:获得锁的线程崩溃后,不会影响后续线程获取锁,操作共享资源
-
隔离性:A获取的锁,不能让B去解锁(解铃还须系铃人)
-
原子性:加锁和解锁必须保证为原子操作
文章相关视频
分布式锁的实现方式
-
基于Redis 演变过程:
V-1.0:
-
SETNX:Redis提供了SETNE(SET if Not eXists)命令,表示当Key不存在时,才能设置Value,否则设置失败(获取锁失败)
-
DEL KEY:第一步获取锁成功,对共享资源操作完后,释放锁
问题:如果业务代码出现异常,阻塞或者报错了,那么该线程就一直持有锁,不释放,其他线程也永远获取不到————我王霸天得不到的谁也别想得到!
V-2.0:
-
SETNX+EXPIRE:给锁上过期时间,假如持有锁线程崩溃了,达到设置的过期时间后,会自动释放锁,避免后续线程获取不到锁!
问题:仍旧会死锁!SETNX和EXPIRE是两条命令,Redis单命令是原子操作,但多条命令为非原子操作!SETNX执行成功,EXPIRE失败时就会发生死锁 v-3.0:
-
SET(NX+EX)(2.6.12版本之后):获取锁,并设置锁过期时间(原子操作)
如此,可以说是彻底解决了死锁问题!
那么还问存在其他问题吗?
分析分布式锁的特征:互斥、死锁、原子等特性,我们都算是解决了!
但还未考虑隔离性的问题!
场景
-
线程A加锁成功后,去操作共享资源
-
但是因为发生了意外,线程A操作的时间超过了锁过期时间,锁被释放了
-
线程B进来了,枷锁成功,去操作共享资源了
-
此时&