前言
因为在分布式框架中给程序加锁,要考虑锁超时、死锁、释放锁,简单的使用redis set命令并不满足高并发场景下的业务,所以需要对这些情况进行容错。
RedisTemplate方式实现(大并发量情况下有锁超时的缺陷)
// -------------------普通redis操作-----------------------------
String lockName = "buyLock";
//clientid是为了防止错误释放锁,进行认证
String clientId = UUID.randomUUID().toString();
//模拟商品
redis.set("stock",100);
//1.尝试获取锁,设置超时时间是防止一直占用锁
if(redis.setNX(lockName,clientId,10)){
return "当前获取锁失败,商品抢购失败!";
}
try{
//2.商品数量-1
redis.set("stock",100-1);
}catch (Exception e){
//这里加catch是为了防止如果出现逻辑异常引发死锁
e.printStackTrace();
}finally {
//只有锁持有人才可以释放锁
if(redis.get(lockName).equals(clientId)){
//3.释放锁
redis.delNX(lockName);
}
}
return "购买成功!";
// -------------------------------------------------------------------
Redisson解决锁续命问题
springBoot集成步骤
1.引入工程
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
2.创建bean
在启动类中添加bean,这里仅仅展示单机redisserver,其中还有哨兵模式、cluster集群模式的server可以参考官网
@Bean
public Redisson redisson(){
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.195.128:6379").setPassword("123456").setDatabase(0);
return (Redisson) Redisson.create(config);
}
3.代码实现
// -----------------------------redisson操作------------------------------
String lockName = "buyLock";
RLock redisLock = redisson.getLock(lockName);//创建锁
redisLock.lock();//加锁,默认10s超时,自动续命,自旋锁
try{
//2.商品数量-1
redis.set("stock",100-1);
}catch (Exception e){
//这里加catch是为了防止如果出现逻辑异常引发死锁
e.printStackTrace();
}finally {
//3.释放锁
redisLock.unlock();
}
return "购买成功!";
// -----------------------------redisson操作------------------------------
demo地址
github地址
不会下载的可以留言我给你发过去