redis实现分布式锁

先上代码

import redis.clients.jedis.JedisPool;
import java.util.Collections;

public class RedisLock {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
private JedisPool pool;
public RedisLock(JedisPool pool) {
this.pool = pool;
}

/**
* 尝试获取分布式锁
* @param lockKey 锁 比如user_id
* @param requestId 请求标识 比如 uuid
* @param expireTime 超期时间
* @return 是否获取成功
*/

public boolean tryDistributedLock( String lockKey, String requestId,

int expireTime) {

String result = pool .getResource().set(lockKey , requestId , SET_IF_NOT_EXIST , SET_WITH_EXPIRE_TIME , expireTime) ;
if ( LOCK_SUCCESS .equals(result)) {
return true;
}
return false;
}
/**
* 释放分布式锁
* @param lockKey 锁 比如 user_id
* @param requestId 请求标识 获取所的时候的uuid
* @return 是否释放成功
*/
public boolean releaseDistributedLock (String lockKey , String requestId) {

String script = "if redis.call('get', KEYS[1]) == ARGV[1]

then return redis.call('del', KEYS[1]) else return 0 end";

Object result = pool .getResource().eval(script , Collections. singletonList (lockKey) , Collections. singletonList (requestId)) ;
if ( RELEASE_SUCCESS .equals(result)) {
return true;
}
return false;
}
}


首先满足setnx+expire的原子性,然后引入了lua脚本,也是为保证delete的原子性。首先获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁(解锁)。那么为什么要使用Lua语言来实现呢?因为要确保上述操作是原子性的。

简单来说,就是在eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令。

redis实现分布式锁_第1张图片


你可能感兴趣的:(redis实现分布式锁)