Redis分布式锁【简单版】

概要

redis分布式锁六种方案

  1. SETNX + EXPIRE 方案

    • 描述:使用Redis的SETNX命令来尝试设置一个键值对,如果该键不存在,则设置成功并设置过期时间,实现锁的功能。
  2. SETNX + value值 方案

    • 描述:通过SETNX命令尝试设置键值对,并将值设置为当前系统时间加上锁的过期时间,锁的释放可以通过比较值来判断是否过期。
  3. Lua脚本 方案

    • 描述:使用Lua脚本结合SETNX和EXPIRE两条指令,通过保证原子性来实现分布式锁。
  4. SET的扩展命令(SET EX PX NX)方案

    • 描述:利用Redis的SET命令的扩展参数,结合EX、PX和NX参数,可以一步完成锁的设置。
  5. 开源框架 Redisson 方案

    • 描述:Redisson是一个基于Redis的Java框架,提供了分布式锁等多种分布式功能的实现,简化了开发者的工作。
  6. 多机实现的分布式锁 Redlock 方案

    • 描述:Redlock通过在多个Redis节点上获取锁,并使用时钟同步算法确保锁的可靠性和一致性。

例子1【SETNX + EXPIRE】

public class Test {

    private static final String LOCK_KEY = "my_lock";

    public static void main(String[] args) {
        // 连接到Redis服务器
        Jedis jedis = new Jedis("122.51.159.21", 6379);
        // 获取锁
        if (acquireLock(jedis, LOCK_KEY)) {
            try {
                // 执行需要加锁的业务逻辑
                System.out.println("锁已获取。正在执行关键部分...");
                // 模拟业务处理时间
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 保证释放锁
                releaseLock(jedis, LOCK_KEY);
            }
        } else {
            System.out.println("无法获取锁。另一个进程持有该锁。");
        }

        // 关闭连接
        jedis.close();
    }

    private static boolean acquireLock(Jedis jedis, String lockKey) {
        // 尝试设置锁,如果成功返回1,否则返回0
        Long result = jedis.setnx(lockKey, "locked");
        if (result == 1) {
            // 设置锁的过期时间
            jedis.expire(lockKey, 30);// 过期时间 30s
            return true;
        }
        return false;
    }

    private static void releaseLock(Jedis jedis, String lockKey) {
        // 释放锁
        jedis.del(lockKey);
    }
}


此方案缺点:

  1. 在高并发情况下,多个客户端可能同时执行 SETNX 命令并都成功获取锁,导致竞争条件发生
  2. 加锁与与设置过期时间是非原子操作
  3. 如果业务逻辑执行时间超过了过期时间,锁可能会在业务逻辑执行完之前被自动释放

例子2【 Redisson 】

public class Test {

    public static void main(String[] args) {
        // 创建 Redisson 客户端连接
        Config config = new Config();
        config.useSingleServer().setAddress("redis://122.51.159.21:6379");
        RedissonClient redisson = Redisson.create(config);

        // 获取分布式锁
        RLock lock = redisson.getLock("my_lock");

        try {
            // 尝试加锁,最多等待 10 秒,锁的持有时间为 20 秒
            boolean isLocked = lock.tryLock(10, 20, java.util.concurrent.TimeUnit.SECONDS);
            if (isLocked) {
                // 成功获取到锁
                System.out.println("成功获取到锁,执行业务逻辑...");
                // 在这里执行你的业务逻辑
            } else {
                // 获取锁失败
                System.out.println("获取锁超时,未能执行业务逻辑...");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 释放锁
            lock.unlock();
        }

        // 关闭 Redisson 客户端连接
        redisson.shutdown();
    }
}

Redisson解决了:锁过期释放,业务没执行完。
Redisson中watch dog看门狗可以去了解下。


❤觉得有用的可以留个关注❤

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值