基于redisson实现分布式锁
作者:互联网
在日常业务开发中,为了解决并发问题,比如,同一个时刻,多笔相同订单号的订单同时请求,我们只会受理一笔,其他的请求拒绝。我们通常都是用分布锁来解决,当然,也可以使用数据库的唯一索引来解决,数据新增的时候会报插入异常,这样如果系统并发很大,会给数据库造成很大的压力,通常都不会这么操作。
实现分布式锁的方案有很多种,比如用 zookeeper、redis等中间件,本文主要介绍使用 redission 实现分布锁,主要原因有以下几点:
- 生产有redis 哨兵集群,不需要在部署其他中间件环境
- redission 有看门狗机制,能自动给分布式锁延期(这个可以网上搜索参考其他文章)
一、环境说明
maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.2</version>
</dependency>
二、代码实现
@Configuration
@Setter
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
public class RedisClientConfig {
@Value("${redis.clusterName}")
private String clusterName;
@Value("${redis1.host}")
private String redis1Host;
@Value("${redis1.port}")
private Integer redis1Port;
@Value("${redis2.host}")
private String redis2Host;
@Value("${redis2.port}")
private Integer redis2Port;
@Value("${redis3.host}")
private String redis3Host;
@Value("${redis3.port}")
private Integer redis3Port;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSentinelServers()
.setMasterName(clusterName)
.addSentinelAddress("redis://"+redis1Host+":"+redis1Port)
.addSentinelAddress("redis://"+redis2Host+":"+redis2Port)
.addSentinelAddress("redis://"+redis3Host+":"+redis3Port);
return Redisson.create(config);
}
}
/**
* redis 分布式锁
*/
@Component
@Slf4j
public class RedisLock {
@Autowired
private RedissonClient redissonClient;
/**
* 尝试拿锁 waitTime 后停止重试,返回false
* @param lockKey 锁key值
* @param unit 时间单位
* @param waitTime 等待时间
* @return 是否获取锁成功
*/
public boolean tryLock(String lockKey, long waitTime,long leaseTime,TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime,leaseTime, unit);
} catch (InterruptedException e) {
log.error("获取redis分布式锁异常",e);
return false;
}
}
/**
* 尝试拿锁,不重试,获取不到,返回false
* 具有Watch Dog 自动延期机制 默认续30s
* @param lockKey
* @return
*/
public boolean tryLock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(0L, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("获取redis分布式锁异常",e);
return false;
}
}
/**
* 释放锁
* @param lockKey
*/
public void unlock(String lockKey) {
try {
RLock lock = redissonClient.getLock(lockKey);
if(lock.isLocked()){
lock.unlock();
}
} catch (Exception e) {
log.error("释放锁异常",e);
}
}
}
标签:基于,redisson,return,String,lock,redis,private,lockKey,分布式 来源: https://www.cnblogs.com/wallacepang/p/16215679.html