Welcome everyone

一个Redis简易的分布式锁实现

redis 汪明鑫 450浏览 0评论

在一些简单的业务场景下,其实不用考虑锁的重入、重试等问题,也很少需要考虑Redis主从切换,分布式锁失效。

那么一种最简单的分布式锁实现,其实就是Redis setNX, 其实已经能满足大多数场景了

直接上代码:

public class RedisDistributedLock {
    private static final String KEY_PREFIX = "dl";

    /**
     * @param userId      uid
     * @param lockBizType 业务类型,
     */
    public static DistributedLock getDLockWithRetry(long userId, int lockBizType) {
        String key = getKey(userId, lockBizType);

        DistributedLock distributedLock = null;
        try {
            long expireMillis = 10000;  //给个过期时间
            distributedLock = new DistributedLock(key, expireMillis);
            distributedLock.acquireLock();
        } catch (Exception e) {
            // log
        }

        return distributedLock;
    }

    public static void releaseDLock(DistributedLock lock) {
        if (lock == null || lock.isFailure()) {
            return;
        }

        MoreFunctions.runCatching(lock::releaseLock);
    }

    private static String getKey(long userId, int lockBizType) {
        return Joiner.on("_").join(KEY_PREFIX, lockBizType.name(), userId);
    }

    /**
     * 分布式锁
     */
    public static class DistributedLock {
        private String key;

        private String value;

        private Jedis jedis = new Jedis("xxx", 6668);

        private long expireMillis;

        private boolean success = false;

        public DistributedLock(String key, long expireMillis) {
            this.key = key;
            this.value = String.valueOf(System.currentTimeMillis());
            this.expireMillis = expireMillis;
           
        }

        public String getKey() {
            return key;
        }

        public boolean isSuccess() {
            return success;
        }

        public boolean isFailure() {
            return !isSuccess();
        }

        public String getValue() {
            return value;
        }

        public boolean acquireLock() {
            String result = this.jedis
                    .set(this.key, this.value, "NX", "PX", this.expireMillis);
            this.success = "OK".equalsIgnoreCase(result);
            return this.success;
        }

        public void releaseLock() {
          this.jedis.del(this.key);
        }
    }
}

使用锁:

RedisDistributedLock.DistributedLock lock = null;
        try {
            lock =RedisDistributedLock
                    .getDLockWithRetry(userId, 1);
            if (!lock.isSuccess()) {
                // 打点日志 + 抛异常
            }

            return doXxx(userId);
        } finally {
            if (Objects.nonNull(lock)) {
                RedisDistributedLock.releaseDLock(lock);
            }
        }

转载请注明:汪明鑫的个人博客 » 一个Redis简易的分布式锁实现

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz