redis实现分布式锁

前情提要:

  • SETNX:将key的值设置为value,当且仅当key不存在(version>=1.0),对应springBoot RedisTemplate的setIfAbsent(key,value);
简单方法一

代码片.

String lockKey = "lockKey";
Boolean result = stringRedisTemplate.opsValue.setIfAbsent(lockKey,"value");//jedis.setnx(key,value)
if(!result){
    return "error_code";
}

//业务代码...

stringRedisTemplate.delete(lockKey);

可能出现的问题:

  1. 业务抛异常,锁无法释放。
  2. 业务代码的时候服务被kill,导致锁无法释放
  3. 加锁时间太短业务没执行被释放,太长影响性能,到底多少时间合适? – 可以使用timer实现,扫描key,延长过期时间
简单方式二(加超时时间,解决问题1,2)基本可用:
String lockKey = "lockKey";
//1
Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockKey,"value");//jedis.setnx(key,value)
//2
stringRedisTemplate.expire(lockKey,10,TimeUnit.SECONDS)

//3 (合并1和2)
Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockKey,"value",10,TimeUnit.SECONDS)

if(!result){
    return "error_code";
}
try{

    //业务代码...

}finally{
    stringRedisTemplate.delete(lockKey);
}
  • 说明:3代码可以解决1和2执行中间服务崩溃

可能出现的问题:

  1. 在高并发下A线程加的锁,被其他线程释放掉,导致锁基本无用
方式三(线程只能释放自己加的锁):
String lockKey = "lockKey";
String clientId = UUID.randomUUID.toString();
//3 (合并1和2)
Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockKey,clientId,10,TimeUnit.SECONDS)
if(!result){
    return "error_code";
}
try{

    //业务代码...

}finally{
     if(clientId.equals(stringRedisTemplate.opsForValue.get(lockKay))){
        stringRedisTemplate.delete(lockKey);
    }
}
Redisson实现分布式锁:
String lockKey = "lockKey";
RLock redissonLock = redisson.getLock(lockKey);

try{
    redissonLock.lock();

//业务代码...
}finally{
    redissonLock.unlock();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值