使用Redis SETNX 命令實現分佈式鎖

使用Redis的 SETNX 命令能夠實現分佈式鎖,下文介紹其實現方法。redis

1,實現StringRedisConnection的setNX和getSet接口json

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 {
                            // 已被其餘進程獲取鎖
                        }
                    }
                    
                }
            }
相關文章
相關標籤/搜索