项目中迁移,发现项目中有使用两种分布式锁,redission锁和redis的setIfAbsent锁。虽然redission简单方便好用,但是测试下来发现速度很慢,会导致响应超时的情况,影响前端响应。然后打算用setIfAbsent写在需要有及时响应的接口上。但是测试时加锁不上、空异常,因对本次异常做个解决方案和使用方法做个记录。
出现的问题
由于redission版本导致redis的setIfAbsent返回空。
.前提redis版本使用spring内置的版本
![](https://i-blog.csdnimg.cn/blog_migrate/400a7901354d8e143ff859f76c37f5f4.png)
.pom文件改动,升级redission版本在3.16以上
![](https://i-blog.csdnimg.cn/blog_migrate/b8c4909331c70835a803393a3b995d4c.png)
.application.yml文件改动,配置改为文件引用
![](https://i-blog.csdnimg.cn/blog_migrate/6730fc156c2a26567e1b4da85d009e32.png)
.redission.yml配置文件改动
![](https://i-blog.csdnimg.cn/blog_migrate/53d48941d5578bd4b232f73479a4a6e0.png)
setIfAbsent使用示例
setIfAbsent方法等同于SETNX命令,加锁和设置过期时间必须是一个原子操作,在调用setIfAbsent传入锁名的同时必须传入过期时间。设置的过期时间一般大于业务执行的最大时间,value存入一个uuid,释放的时候先查询是否存在该uuid再释放,保证释放的是同一线程的锁。
![](https://i-blog.csdnimg.cn/blog_migrate/70b2bc13e1d74096895595ab43bd4f88.png)
redission使用示例
未设置过期时间(-1)时则会有watchDog 的锁续约,释放锁判断是否为同一线程的锁。
lock会阻塞,trylock加锁失败会返回false,所以使用trylock释放锁的时候需要判断锁的状态
![](https://i-blog.csdnimg.cn/blog_migrate/6222bb8a10bc260dc13a5b411aab1aad.png)