//第一种
// 上锁
public static Boolean lock(Jedis jedis, String lockKey, String requestId, int expireTime) {
Long result = jedis.setnx(lockKey, requestId);
if (result == 1) {
// 若在这里程序突然崩溃,则无法设置过期时间,将发生死锁
jedis.expire(lockKey, expireTime);
return true;
}
return false;
}
// 释放
public static void releaselock1(Jedis jedis, String lockKey) {
jedis.del(lockKey);
}
//第二 种
@Component
class RedisLock{
private static Logger logger = LoggerFactory.getLogger(RedisLock.class);
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "EX";
private static final Long RELEASE_SUCCESS = 1L;
/**
* 加分布式锁
* @param lockKey key
* @param requestId 唯一的标识(比如可以用uuid),用来实现自己加的锁只有自己才能解锁,防止别人误解锁
* @param expireTime 锁过期时间,单位:秒
* @return 加锁成功返回true, 失败返回false
*/
public boolean lock(final String lockKey, final String requestId, final int expireTime) {
if (StringUtil.isEmpty(lockKey) || StringUtil.isEmpty(requestId) || expireTime <= 0) {
return false;
}
return redisTemplate().execute(new RedisCallback<Boolean>(){
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
Object nativeConnection = connection.getNativeConnection();
String exceptionStr = null;
try {
String result = null;
// 集群模式
if (nativeConnection instanceof JedisCluster) {
result = ((JedisCluster) nativeConnection).set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
}
// 单机模式
else if (nativeConnection instanceof Jedis) {
result = ((Jedis) nativeConnection).set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
}
if (LOCK_SUCCESS.equals(result)) {
return true;
}
else {
return false;
}
}
catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
});
}
/**
* 解锁
* @param lockKey key
* @param requestId 唯一的标识(比如可以用uuid),用来实现自己加的锁只有自己才能解锁,防止别人误解锁
* @return 解锁成功返回true, 失败返回false
*/
public boolean unlock(final String lockKey, final String requestId) {
if (StringUtil.isEmpty(lockKey) || StringUtil.isEmpty(requestId)) {
return false;
}
final String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
return getRedisTemplate().execute(new RedisCallback<Boolean>(){
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
Object nativeConnection = connection.getNativeConnection();
String exceptionStr = null;
try {
Object result = null;
// 集群模式
if (nativeConnection instanceof JedisCluster) {
result = ((JedisCluster) nativeConnection).eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
}
// 单机模式
else if (nativeConnection instanceof Jedis) {
result = ((Jedis) nativeConnection).eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
}
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
else {
return false;
}
}
catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
});
}
}
redis实现分布式锁
最新推荐文章于 2020-06-18 11:06:11 发布