使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法。

1,实现StringRedisConnection的setNX和getSet接口

public Boolean setNX(final String key, final String jsonString){
        Boolean result =  this.redisTemplate.execute(new RedisCallback<Boolean>(){

            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                StringRedisConnection stringRedisConnection = (StringRedisConnection)connection;
                stringRedisConnection.select(3);
                Boolean result = stringRedisConnection.setNX(key, jsonString);
                return result;
            }
        });
        return result;
    }

    public String getSet(final String key, final String jsonString){
        String result =  this.redisTemplate.execute(new RedisCallback<String>(){

            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                StringRedisConnection stringRedisConnection = (StringRedisConnection)connection;
                stringRedisConnection.select(3);
                String result = stringRedisConnection.getSet(key, jsonString);
                return result;
            }
        });
        return result;
    }

 

2,实现例子

private void acquireLock(String lock) {
        // 设置过期时间为1秒
                int expired = 1000;
                long value = System.currentTimeMillis() + expired + 1; 
                boolean result = redisClient.setNX(lock, String.valueOf(value));
                
                // true代表获得锁成功
                if(result) {
                    // TODO 实现具体业务逻辑
                } else {
                    // 不成功则判断是否死锁
                    Long oldValue  =  Long.valueOf(redisClient.gets(lock));
                    // 于当前时间比较,如果小于当前时间代表已超时
                    if(oldValue < System.currentTimeMillis()) {
                        // 设置并获取旧的值
                        String getValue = redisClient.getSet(lock, String.valueOf(value));
                        if(Long.valueOf(getValue) == oldValue) {
                            // 获取锁成功
                        } else {
                            // 已被其他进程获取锁
                        }
                    }
                    
                }
            }