springboot中redis分布式锁的实现

1.场景还原
在并发的场景,分布式锁是一种比较常规且实用的解决方案;今天笔者就springboot中如何实现redis分布式锁作个讲解
2.关注点
实现redis分布式锁的关键在于设置储存值与过期时间要保证是一个原子性操作,否则会发生死锁
3.实现方案
1、pom依赖

<!--集成redis-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、redis锁实现

/**
 * @auther xxx
 * @date 2018/7/21 10:23
 *
 * redis 分布式锁  加锁与解密配套使用
 */
@Component
@Slf4j
public class RedisLock {
    @Autowired
    private HashRedisTemplate stringRedisTemplate;

    /**
     * 加锁
     * @param key 锁唯一标志
     * @param timeout 超时时间
     * @return
     */
    public boolean lock(String key, long timeout){

        String value = String.valueOf(timeout + System.currentTimeMillis());

        if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){
            return true;
        }

        //判断锁超时,防止死锁
        String currentValue = (String)stringRedisTemplate.opsForValue().get(key);
        //如果锁过期
        if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
            //获取上一个锁的时间value
            String oldValue = (String) stringRedisTemplate.opsForValue().getAndSet(key,value);
            if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue) ){
                //校验是不是上个对应的商品时间戳,也是防止并发
                return true;
            }
        }
        return false;
    }
    /**
     * 解锁
     * @param key
     * @param value
     */
    public void unlock(String key,String value){
        try {
            String currentValue =  (String) stringRedisTemplate.opsForValue().get(key);
            if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value) ){
                stringRedisTemplate.opsForValue().getOperations().delete(key);//删除key
            }
        } catch (Exception e) {
            log.error("[Redis分布式锁] 解锁出现异常了,{}",e);
        }
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值