一、setNX保证原子性(分布式下的线程安全)
结果返回为ture的话就执行后面的代码,如果false的话,就返回失败信息。
释放锁:
二、如果获取锁后 程序抛异常,那么释放锁就不会被执行,怎么办?
解决办法:try 。。。 finally
三、如果在执行过程中服务器宕机了怎么办?
解决办法:因为服务器宕机了finally块也无法执行,就会造成死锁,这是就需要给这个锁添加过期时间 命令是:exprie(锁,时间)
四、如上代码加锁后再设置过期时间会有什么问题?
分析:如果将加锁和过期时间分开写,当程序执行了加锁后,服务器宕机了,则过期时间就失效了,造成死锁。
解决办法:就是用另外一个加锁方法:同时加锁和设置过期时间,要么同时成功,要么同时失败。
stringRedisTemplate. opsForValue ().setIfAbsent(lockKey,value:“zhuge”,timeout: 10,TimeUnit. SECONDs)
五、如果此时服务器的压力很大,整个过程的时间超过了锁的过期时间会发生什么问题?
分析:第一请求会把第二个请求的锁释放掉,会造成锁的永久失效。
解决办法:随机生成一个id作为锁的值,在释放锁之前通过redis锁获取值即id 判断是否是同一个id,是就释放锁。
六、解决长时间没有执行完,锁过期的解决办法:
解决办法:
1、常规办法给获取到的锁的主线程开启一个后台子线程,每个一段时间就去检测是否有锁,如果持有就延长锁的过期时间。
2、通过redisson 框架解决
1、导入坐标
2、注入到spring容器
3、使用对应的api实现功能
七、使用redis主从架构时,在很多请求的高并发下,当一个线程获取到主节点的锁,然后主节点还没来的及给从节点复制时,主节点宕机了。会发生什么问题?
解析:会发生开始一样的问题,锁失效造成后面的线程和开始那一个线程同时执行。
解决办法:采用zookeeper服务架构保证数据一致性
它是在从节点一半以上数据同步了才会给线程反应。如果主节点宕机了选取的从节点一定是同步了数据的哪一个从节点。
方式二:
用redis 做出和zookeeper相识的操作