一、全局ID
/** ID最大值 */
final static long maxNum = 2100000000;
/** 初始ID */
final static long startNum = 1000000000;
/** redis步长 */
final static long redisStepLength = 1;
/**
* 获取redis主键序列号(10位长度)
*
* @return
* @throws RedisException
*/
private long getAtomicLong(String key) throws RedisException {
try {
// 获取redis该key的值
RAtomicLong seqLong = redissonClient.getAtomicLong(key);
if (seqLong.get() > maxNum || seqLong.get() < startNum) {
seqLong.set(startNum);
seqLong.expire(1, TimeUnit.DAYS);
}
seqLong.addAndGet(redisStepLength);
return seqLong.get();
} catch (Exception e) {
log.error("获取redis主键序列号异常: ", e);
return RandomUtils.nextLong(startNum, maxNum);
}
}
/**
* 生成表主键ID流水号
*
* @param key
* redisKEY,结构为param1:param2:param3....
* @return 6+10=16位长度
* @throws RedisException
*/
public Long getSeq_16(String key) throws RedisException {
checkForKey(key);
String DateKEY = DateFormatUtils.format(new Date(), "yyMMdd");
return Long.valueOf(DateKEY + getAtomicLong(key + ":" + DateKEY));
}
二、分布锁
/**
* when the time that thread execute business > leaseTime,it is not safe (maybe
* others have already get the lock);
*
* But we should not hold the lock all the time,setting leaseTime is necessary
*
*
* @param key
* lockKey
* @param waitTime
* 最大等候锁时间
* @param leaseTime
* 过期自动释放锁时间
* @param timeUnit
* 时间单位
* @throws RedisException
* throw when locked failed
*/
public <T> T execute(String key, long waitTime, long leaseTime, TimeUnit timeUnit, LockCallback<T> callback)
throws RedisException {
checkForKey(key);
RLock rLock = redissonClient.getLock(key);
if (StringUtils.isBlank(key) || waitTime <= 0 || leaseTime <= 0 || timeUnit == null) {
throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
}
boolean isLocked = false;
try {
// 尝试获取锁
isLocked = rLock.tryLock(waitTime, leaseTime, timeUnit);
if (!isLocked) {
log.debug("locked failed ,key [{}]", key);
throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
}
return callback.doWithLock();
} catch (InterruptedException e) {
log.debug("locked failed ,key [{}]: ", key, e);
throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
} finally {
if (isLocked) {
log.debug("Unlock {} ", key);
rLock.unlock();
log.debug("Unlock {} SUCCESS", key);
}
}
}
调用分布锁锁的例子
public static void main(String[] args) {
RedisUtils redisUtils = new RedisUtils();
String response;
try {
redisUtils.execute("lock:key:seq", 3000, 4000, TimeUnit.MILLISECONDS, new LockCallback<String>() {
public String doWithLock() {
/*
* do business in Lock
*/
return null;
}
});
} catch (RedisException e) {
/*
* lock failed
*/
}
}