一、为什么引入Redisson分布式锁?
基于上篇文章:使用原生Redis命令实现分布式锁。setnx实现的分布式锁存在以下问题:
1、不可重入:同一个线程无法多次获取同一把锁。
2、不可重试:获取锁只尝试一次就返回false,没有重试机制。
3、超时释放:锁超时释放虽然可以避免死锁,但如果是业务耗时较长,也会导致锁释放,存在安全隐患。
4、主从一致性:如果redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从未同步主中的锁数据,则会出现锁实现。
但是在大多数情况下,使用setnx实现的分布式锁是满足要求的。但是如果对锁要求比较高的情况下,比如:高并发下的分布式场景,还是要考虑的。
二、redisson简介
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包含了各种各样的分布式锁的实现。
参考中文地址:
https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
三、入门实现
3.1、引入jar包
!--引入redis分布式锁redisson框架 -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.5</version>
</dependency>
3.2、配置连接
/**
* @Description: TODO:配置连接Redisson
* @Author: yyalin
* @CreateDate: 2023/8/9 17:04
* @Version: V1.0
*/
@Configuration
public class MyRedissonConfig {
@Bean
public RedissonClient getRedisson() {
// 默认连接地址 127.0.0.1:6379
// RedissonClient redisson = Redisson.create();
//1.创建配置
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
//也可以使用config.useClusterServers()添加集群地址
//2.根据config创建处RedissonClient实例
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
3.3、测试
@ApiOperation(value="测试分布式锁操作", notes="testRedisson")
@GetMapping("/testRedisson")
public String testRedisson() throws InterruptedException {
//1、获取锁(可重入),并指定锁的名称
RLock rLock=redissonClient.getLock("lock:testRedisson");
//2、尝试获取锁,参数分别是:waitTime:获取锁的最大等待时间(期间会重试)
// leaseTime:锁自动释放时间 TimeUnit:时间单位
//tryLock(long waitTime, long leaseTime, TimeUnit unit)
boolean isLock=rLock.tryLock(1,100, TimeUnit.SECONDS);
//3、判断锁获取成功及释放
if(isLock){
try {
log.info("执行正常的业务......");
}catch (Exception e){
log.info("锁获取异常e:"+e);
}finally {
//锁未关闭,则手动释放锁
if(rLock.isLocked()){
rLock.unlock();
log.info("释放锁成功");
}
}
}
return "true";
}
Redisson同时还为分布式锁提供了异步执行的相关方法:
RLock lock = redisson.getLock("anyLock");
lock.lockAsync();
lock.lockAsync(10, TimeUnit.SECONDS);
Future<Boolean> res = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);
RLock对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁,其他进程解锁则会抛出IllegalMonitorStateException错误。
更多详细资料,请关注个人微信公众号或搜索“程序猿小杨”添加。