Redisson分布式锁的使用(附源码)

发布于:2023-04-28 ⋅ 阅读:(199) ⋅ 点赞:(0)

Redisson分布式锁的使用(附源码)

问题背景

Redisson做分布式锁是目前比较流行的方式,但是在使用的过程中遇到一些坑:

  • Redisson的分布式锁只能通过创建锁的线程进行解锁,正所谓解铃还须系铃人,不是同一个线程解锁会报异常
  • 因为Redisson是为锁而生,所以一开始设计的时候,为了防止死锁,默认锁的过期时间为30S
  • 当时我居然傻到用单元测试来测试Redisson的分布式锁,我太傻了,单元测试之后马上就会结束项目运行,那么就没有线程持有锁了,更别说还需要同线程解锁了

注意事项:

项目搭建

1 redisson的默认锁时间为30s

2 添加redisson工具类

package com.yg.redisson.utils;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class DistributedRedisLock {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 加锁
     *
     * @param lockName
     * @return
     */
    public Boolean lock(String lockName) {
        if (redissonClient == null) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }

        try {
            RLock lock = redissonClient.getLock(lockName);
            // 默认是30S释放锁, 这里设置12小时
            lock.lock(12 * 60 * 60L, TimeUnit.SECONDS);
            log.info(" lock [{}] success", lockName);

            return true;
        } catch (Exception e) {
            log.info("加锁失败", e);
            log.error("DistributedRedisLock lock [{}] Exception:", lockName, e);
            return false;
        }
    }


    /**
     * 加锁
     *
     * @param lockName
     * @return
     */
    public Boolean lockWithExpire(String lockName, long expire) {
        if (redissonClient == null) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }

        try {
            RLock lock = redissonClient.getLock(lockName);
            // 锁expire秒后自动释放,防止死锁
            lock.lock(expire, TimeUnit.SECONDS);
            // 加锁成功
            return true;
        } catch (Exception e) {
            log.info("加锁失败", e);
            log.error("DistributedRedisLock lock [{}] Exception:", lockName, e);
            return false;
        }
    }


    /**
     * 释放锁
     *
     * @param lockName
     * @return
     */
    public Boolean unlock(String lockName) {
        if (redissonClient == null) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }

        try {
            RLock lock = redissonClient.getLock(lockName);
            log.info("lock:{}", lock.isLocked());
            log.info("lock.isHeldByCurrentThread: {}", lock.isHeldByCurrentThread());
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
                log.info(" unlock [{}] success", lockName);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("DistributedRedisLock unlock [{}] Exception:", lockName, e);
            return false;
        }
    }
}

3 添加使用分布式锁的服务

package com.yg.redisson.service;

import com.yg.redisson.utils.DistributedRedisLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;


/**
 * @Author suolong
 * @Date 2022/5/7 10:04
 * @Version 2.0
 */
@Slf4j
@Service
public class RedissonService {

    @Autowired
    DistributedRedisLock distributedRedisLock;

    @PostConstruct
    public void distributeLockTest(){
        String lockName = "yuange";
        //加锁
        if(distributedRedisLock.lock(lockName)){
            log.info("lock success");
            //do something  锁住你要执行的程序
	        /*
	
	         */
        }else{
            log.error("lock failed");
        }

        //解锁
        if(distributedRedisLock.unlock(lockName)){
            log.info("unlock success");
        }else{
            log.error("unlock failed");
        }
    }

}

4 项目目录

总结




作为程序员第 124 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …

Lyric: 如果说分手是苦痛的起点

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到