使用redis的setnx实现分布式锁

在Redis中,SETNX 是 “Set If Not Exists”(如果不存在,则设置)的缩写。这是一个原子操作,用于设置一个键的值,前提是这个键不存在。如果键已经存在,.则不会执行任何操作。

封装方法trylock,用于获取分布式锁

/**
     * 尝试获  取一个锁。
     *
     * @param name   锁的名称,通常是一个资源的标识。
     * @param expire 锁的过期时间,单位为毫秒。
     * @return 如果获取锁成功,返回一个唯一的token;如果失败,则返回null。
     */
    public String tryLock(String name, long expire) {
        // 为锁名称添加后缀,以避免命名冲突
        name = name + "_lock";
        // 生成一个唯一的token,用于标识持有锁的客户端
        String token = UUID.randomUUID().toString();
        // 获取Redis连接工厂
        RedisConnectionFactory factory = stringRedisTemplate.getConnectionFactory();
        // 获取Redis连接
        RedisConnection conn = factory.getConnection();
        try {
            // 使用SET命令尝试以NX选项(只在键不存在时设置)设置键值对,如果成功,返回true
            // 这里使用了Expiration指定键的过期时间,以确保锁在一段时间后自动释放
            // 参考redis命令:SET key value [EX seconds] [PX milliseconds] [NX|XX]
            Boolean result = conn.set(
                    name.getBytes(), //key
                    token.getBytes(), //value
                    Expiration.from(expire, TimeUnit.MILLISECONDS),
                    RedisStringCommands.SetOption.SET_IF_ABSENT // NX
            );
            // 如果设置成功,返回生成的token
            if (result != null && result)
                return token;
        } finally {
            // 释放Redis连接
            RedisConnectionUtils.releaseConnection(conn, factory, false);
        }
        // 如果未能成功获取锁,返回null
        return null;
    }

接下来,你可以在需要防止并发执行的方法中使用tryLock方法:

	public void exampleMethod(String taskName) {
		String lockKey = "myLockKey";
        // 尝试获取锁
        String token = tryLock(lockKey, 10000); // 锁过期时间为10秒
        if (token != null) {
            try {
                // 获取锁成功,执行业务逻辑
                System.out.println("所获取成功");
                // 模拟任务执行
                // ...
            } finally {
                // 释放锁
                stringRedisTemplate.delete(lockKey+ "_lock");
            }
        } else {
            // 获取锁失败,处理失败逻辑
            System.out.println("获取锁失败");
        }
    }

相关推荐

  1. 使用redissetnx实现分布式

    2024-06-07 04:22:05       35 阅读
  2. redissetnx实现分布式

    2024-06-07 04:22:05       32 阅读
  3. redis setnx使用方法

    2024-06-07 04:22:05       21 阅读
  4. Redis实现分布式

    2024-06-07 04:22:05       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 04:22:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 04:22:05       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 04:22:05       82 阅读
  4. Python语言-面向对象

    2024-06-07 04:22:05       91 阅读

热门阅读

  1. vue-router 源码分析——3. 动态路由匹配

    2024-06-07 04:22:05       29 阅读
  2. flutter sdk升级之空安全启用

    2024-06-07 04:22:05       34 阅读
  3. C++容器之前向链表(std::forward_list)

    2024-06-07 04:22:05       33 阅读
  4. PDF文件处理不再复杂:9个Python库让一切变得简单

    2024-06-07 04:22:05       26 阅读
  5. 如何使用ChatGPT写出爆款自媒体短视频文案

    2024-06-07 04:22:05       33 阅读
  6. 嵌入式软件中static的用法

    2024-06-07 04:22:05       34 阅读