💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
![](https://img.kancloud.cn/94/85/9485b0177ec6a72e9d79a4ad15cf57ce_720x583.png) ## 1 非原子操作: setnx+expire操作过程中, 但是redis中`setnx`+`expire`是非原子操作,如果expire无法执行, 会导致死锁 ## 2 忘了释放锁 原生命令格式: ``` SET key value [EX seconds] [PX milliseconds] [NX|XX] EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。 PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒(千分之一秒)。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。 NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。 XX : 只在键已经存在时, 才对键进行设置操作 ``` 分布式锁更合理的用法是: 1. 手动加锁 2. 业务操作 3. 手动释放锁 4. 如果手动释放锁失败了,则达到超时时间,redis会自动释放锁。 ![](https://img.kancloud.cn/00/5e/005e1e9d306aed2fc3207fa9fd8dfee6_720x509.png) ## 3 释放了别人的锁 假如线程A和线程B,都使用lockKey加锁。线程A加锁成功了,但是由于业务功能耗时时间很长,超过了设置的超时时间。这时候,redis会自动释放lockKey锁。此时,线程B就能给lockKey加锁成功了,接下来执行它的业务操作。恰好这个时候,线程A执行完了业务功能,接下来,在finally方法中释放了锁lockKey。这不就出问题了,线程B的锁,被线程A释放了。 ![](https://img.kancloud.cn/71/cb/71cbdb46e1deef56c657da3317907370_919x440.png)