基于Redisson的Redis分布式锁

Redisson分布式锁_redissonclient_甩锅虾的博客-CSDN博客

 

**
 * 分布式锁
 */
public interface DistributedLock {

    /**
     * 尝试获取锁
     * @param lockName
     * @param seconds
     * @return
     */
    Boolean tryAcquire(String lockName, long seconds, TimeUnit unit);

    /**
     * 释放锁
     * @param lockKey
     */
    void release(String lockKey);

    /**
     * 获取锁
     * @param lockKey
     * @return
     */
    Boolean acquire(String lockKey, long seconds, TimeUnit unit);
}



/**
 * 基于 redisson 封装分布式锁
 */
@Component
@Slf4j
public class DistributedRedisLock implements DistributedLock {

    @Autowired
    private RedissonClient redisson;

    private static final String LOCK_TITLE = "DistributedRedisLock:";

    @Override
    public Boolean tryAcquire(String lockKey, long seconds, TimeUnit unit) {
        RLock lock = redisson.getLock(LOCK_TITLE + lockKey);
        try {
            boolean b = lock.tryLock(0, seconds, unit);
            if (b) {
                log.info("获取锁成功");
                return true;
            }else {
                log.info("获取锁失败");
                return false;
            }
        }catch (InterruptedException e) {
            log.error("try acquire distributed lock error : [{}]",e.getMessage(),e);
            return false;
        }
    }

    /**
     * 默认以秒为单位 尝试获取锁
     * @param lockKey
     * @param seconds
     * @return
     */
    public Boolean tryAcquire(String lockKey, long seconds) {
        return tryAcquire(lockKey,seconds,TimeUnit.SECONDS);
    }

    @Override
    public void release(String lockKey) {
        RLock lock = redisson.getLock(LOCK_TITLE + lockKey);

        //判断是否上锁
        if (lock.isLocked()) {
            //是否还在锁定
            if (lock.isHeldByCurrentThread()) {
                //是否是当前线程所持有的锁
                //释放锁
                lock.unlock();
                log.info("unlock: [{}]",lockKey);
            }
        }
    }

    @Override
    public Boolean acquire(String lockKey,long seconds,TimeUnit unit) {
        String key = LOCK_TITLE + lockKey;
        //获取锁对象
        RLock lock = redisson.getLock(key);
        //加锁,设置过期时间
        lock.lock(seconds,unit);
        log.info("distributed lock locked : [{}]",key);
        return true;
    }

    /**
     * 默认以秒为单位获取锁,设置锁租期不触发 watchdog
     * @param lockKey
     * @param seconds
     * @return
     */
    public Boolean acquire(String lockKey,long seconds) {
        return acquire(lockKey,seconds,TimeUnit.SECONDS);
    }

    /**
     * 默认获取锁 过期时间默认 30s 为获取到锁的线程阻塞 能触发 watchdog
     * @param lockKey
     * @return
     */
    public Boolean acquire(String lockKey) {
        String key = LOCK_TITLE + lockKey;
        //获取锁对象
        RLock lock = redisson.getLock(key);
        lock.lock();
        log.info("distributed lock locked : [{}]",key);
        return true;
    }

}


// 具体的业务应用测试
public class Test {

    /**
     * redis锁
     */
    @Autowired
    private DistributedRedisLock redisLock;

    /**
     * lock
     */
    public void testLock() {
        String key = "加锁具体的key";

        // 加锁
        redisLock.acquire(key, 10);

        try {
            // 业务逻辑
        } catch (NoTransactionException e) {
            //日志
        } finally {
            // 释放锁
            redisLock.release(key);
        }
    }

    /**
     * tryLock
     */
    public void testTryLock() {
        String key = "加锁具体的key";

        //加锁
        Boolean isSuccess = redisLock.tryAcquire(key, 10);
        if (isSuccess) {
            //加锁成功
            Object result = null;
            try {
                // 业务逻辑
            } catch (Exception e) {
                // 日志
            } finally {
                redisLock.release(key);
            }
        } else {
            //获取锁失败处理逻辑
        }
    }
}

lock() 与 tryLock() 的区别

(1)返回值: lock() 是没有返回值的;tryLock() 的返回值是 boolean。
 

(2)时机:lock() 一直等锁释放;tryLock() 获取到锁返回true,获取不到锁并直接返回false。
 

(3)tryLock() 是可以被打断的,被中断的;lock是不可以。

你可能感兴趣的:(redis,分布式,数据库)