redis分布式锁setnx

package com.realize;

import redis.clients.jedis.Jedis;
import java.util.UUID;
import redis.clients.jedis.params.SetParams;

public class DistributedLock {

    private Jedis jedis;
    private String lockKey;
    private String lockValue;
    private int expireTime;

    public DistributedLock(Jedis jedis, String lockKey, int expireTime) {
        this.jedis = jedis;
        this.lockKey = lockKey;
        this.expireTime = expireTime;
    }

    // 获取锁
    public boolean acquireLock() {
        this.lockValue = UUID.randomUUID().toString();
        //String result = jedis.set(lockKey, lockValue, "NX", "EX", expireTime);
        String result = jedis.set(lockKey, lockValue,SetParams.setParams().nx().ex(10L));
        return "OK".equals(result);
    }

    // 释放锁
    public boolean releaseLock() {
        String luaScript =
                "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                        "return redis.call('del', KEYS[1]) " +
                        "else " +
                        "return 0 " +
                        "end";
        Object result = jedis.eval(luaScript, 1, lockKey, lockValue);
        return result.equals(1L);
    }

    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        DistributedLock lock = new DistributedLock(jedis, "resource_lock", 10);

        if (lock.acquireLock()) {
            try {
                System.out.println("Lock acquired, doing some work...");
                // 执行业务逻辑
            } finally {
                lock.releaseLock();
                System.out.println("Lock released");
            }
        } else {
            System.out.println("Failed to acquire lock");
        }

        jedis.close();
    }
}

  • 注意事项
  • 唯一标识符:使用唯一标识符来标识每个持有锁的客户端,防止锁被错误释放。
  • 过期时间:设置合理的过期时间,防止死锁。如果客户端在持有锁期间崩溃,过期时间可以自动释放锁。
  • 重试机制:获取锁时可以设置重试机制,防止短暂的争用导致获取锁失败。
  • 使用场景

    SET NX 命令通常用于实现分布式锁,以确保在分布式环境中,同一时间只有一个客户端可以持有锁,从而避免并发访问导致的数据不一致问题。

  • 获取锁:

    lockValue:生成一个唯一标识符,作为锁的值。
    jedis.set(lockKey, lockValue, "NX", "EX", expireTime):尝试使用 SET NX 命令设置锁。只有在 lockKey 不存在时,才能成功设置该键,并指定过期时间 expireTime。

Redis分布式锁的实现可以使用RedisSETNX命令(SET if Not eXists)来完成。SETNX命令在键不存在时设置键的值,如果键已经存在则不执行任何操作。 以下是使用SETNX命令实现Redis分布式锁的示例代码(使用Python语言): ```python import redis def acquire_lock(redis_conn, lock_key, expire_time): # 使用SETNX命令尝试获取锁 lock_acquired = redis_conn.setnx(lock_key, 1) if lock_acquired: # 设置锁的过期时间 redis_conn.expire(lock_key, expire_time) return True else: return False def release_lock(redis_conn, lock_key): # 释放锁,删除键 redis_conn.delete(lock_key) # 创建Redis连接 redis_conn = redis.Redis(host='localhost', port=6379, db=0) # 获取锁 if acquire_lock(redis_conn, 'mylock', 10): try: # 执行业务逻辑 print("Lock acquired. Do something here...") finally: # 释放锁 release_lock(redis_conn, 'mylock') else: print("Failed to acquire lock. Another process holds the lock.") ``` 以上代码中,`acquire_lock`函数尝试获取锁并设置过期时间,如果成功获取到锁则返回True,否则返回False。`release_lock`函数用于释放锁,即删除键。 在使用分布式锁时,可以根据具体业务需求设置合适的锁键(`lock_key`)和过期时间(`expire_time`)。确保在获取到锁之后,执行业务逻辑的代码在适当的位置调用`release_lock`函数释放锁,避免锁一直被占用而无法释放。 需要注意的是,RedisSETNX命令是原子操作,可以确保在并发情况下只有一个客户端能够成功获取到锁。同时,设置合适的过期时间能够避免因为异常情况导致锁一直被占用而无法释放。 这只是一个简单的示例,实际使用中还需要考虑异常处理、加锁失败的重试策略以及其他线程安全的因素,以确保分布式锁的可靠性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值