springboot中redis分布式锁的实现

1.场景还原

    在并发的场景,分布式锁是一种比较常规且实用的解决方案;今天笔者就springboot中如何实现redis分布式锁作个讲解

2.关注点

    实现redis分布式锁的关键在于设置储存值与过期时间要保证是一个原子性操作,否则会发生死锁;笔者在springmvc中也讲解了redis分布式锁的实现,跟springboot的实现不一样,有兴趣的同学可以去看看

博文链接:https://blog.csdn.net/zhangxing52077/article/details/79484445

3.实现方案

①pom依赖

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

②redis锁实现

/**
 * @auther zx
 * @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);
        }
    }

}

这里对setnx时候的线程中断或者其他异常导致的死锁进行了相应的处理

好了,我是张星,欢迎加入博主技术交流群,群号:526601468

猜你喜欢

转载自blog.csdn.net/zhangxing52077/article/details/81143860