import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public class RedisDistributedLock {
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 String UNLOCK_LUA = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
@Resource
private RedisTemplate<String, String> redisTemplate;
public boolean tryGetDistributedLock(String key, String requestId, long expireTime, TimeUnit timeUnit) {
try {
RedisCallback<String> callback = (connection) -> {
JedisCommands commands = (JedisCommands) connection.getNativeConnection();
return commands.set(key, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, timeUnit.toMillis(expireTime));
};
return LOCK_SUCCESS.equals(redisTemplate.execute(callback));
} catch (Exception e) {
LogUtils.error("set redis occured an exception", e);
}
return false;
}
public boolean releaseDistributedLock(String key, String requestId) {
try {
List<String> keys = Collections.singletonList(key);
List<String> args = Collections.singletonList(requestId);
RedisCallback<Long> callback = (connection) -> {
Object nativeConnection = connection.getNativeConnection();
if (nativeConnection instanceof JedisCluster) {
return (Long) ((JedisCluster) nativeConnection).eval(UNLOCK_LUA, keys, args);
}
else if (nativeConnection instanceof Jedis) {
return (Long) ((Jedis) nativeConnection).eval(UNLOCK_LUA, keys, args);
}
return 0L;
};
Long result = redisTemplate.execute(callback);
return result != null && result > 0;
} catch (Exception e) {
LogUtils.error("release lock occured an exception", e);
}
return false;
}
}
private void doSome(List<POJO> list) {
String lockeds = null, lockRequestId = UUID.randomUUID().toString();
try {
if (!redisDistributedLock.tryGetDistributedLock(lockeds, lockRequestId, requestLock.getTimeout(), requestLock.getUnit())) {
LogUtils.info("分布式锁已存在,=" + bdmCarBOMTreeMdl.getMtlNO() + ", 锁=" + lockeds);
return;
}
LogUtils.info("加分布式锁成功,=" + bdmCarBOMTreeMdl.getMtlNO() + ", 锁=" + lockeds);
System.out.println("执行锁内业务。。。。。。。");
} catch (Exception e) {
LogUtils.error(ContractConstants.ERROR, e);
} finally {
if (!redisDistributedLock.releaseDistributedLock(lockeds, lockRequestId)) {
LogUtils.warn("解分布式锁失败, 请求参数=" + bdmCarBOMTreeMdl + ", 物料号=" + bdmCarBOMTreeMdl.getMtlNO() + ", 锁=" + lockeds);
} else {
LogUtils.info("分布式解锁成功,物料号=" + bdmCarBOMTreeMdl.getMtlNO() + ", 锁=" + lockeds);
}
}
});
});