//redission 客户端
@Component
public class RedisUUID {
@Autowired
private RedisTemplate redisTemplate ;
private UUIDStorage defaultUUIDStorage;
private RedissonClient redissonClient;
public RedisUUID(UUIDStorage defaultUUIDStorage , RedissonClient redissonClient){
this.defaultUUIDStorage = defaultUUIDStorage;
this.redissonClient =redissonClient;
}
public String generateUUID(String key , Long expireTime ,TimeUnit timeUnit, UUIDStorage uuidStorage ){
RedisAtomicLong uuidLong = new RedisAtomicLong(key,redisTemplate.getConnectionFactory());
Long expire = uuidLong.getExpire();
if(expire == -1 && expireTime!=null && timeUnit!=null ){
uuidLong.expire(expireTime,timeUnit);
}
return uuidStorage == null ?defaultUUIDStorage.generate(uuidLong):uuidStorage.generate(uuidLong) ;
}
public RedissonClient getRedissonClient(){
return this.redissonClient;
}
}
应用案例:
@Override
public String generateCode(Long projectId) {
final String projectCode = projectSubinfoMapper.selectProjectCodeById(projectId);
return redisUUID.generateUUID("pms:projectsubinfo:projectsubinfo:code:" + projectCode, null, null, new UUIDStorage() {
@Override
public String generate(RedisAtomicLong uuidLong) {
Assert.notNull(uuidLong, "生成的ID不能为空");
//如果redis中不存在则查询数据库
if (uuidLong.get() == 0) {
RedissonClient redissonClient = redisUUID.getRedissonClient();
RLock fairLock = redissonClient.getFairLock("pms:pojectsubinfo:code:create" + projectCode);
boolean isLock = false;
try {
isLock = fairLock.tryLock(2, 5, TimeUnit.MILLISECONDS);
if (isLock && uuidLong.get() == 0) {
String maxProjectSubinfoCode = projectSubinfoMapper.selectMaxProjectSubinfoCode(projectId);
//如果数据库中也为空说明是第一次生成
if (maxProjectSubinfoCode == null) {
return projectCode +"P"+ String.format("%03d", uuidLong.incrementAndGet());
//如果不是则将其加1并存入redis
} else {
String maxCodeNum = maxProjectSubinfoCode.substring(maxProjectSubinfoCode.length() - 3, maxProjectSubinfoCode.length());
//去掉头部的0转成Long型
Long maxCode = 0L;
try {
//99%的项目都不会有问题,所以干脆try catch得了
maxCode = Long.parseLong(maxCodeNum.replaceFirst("^0*", ""));
} catch (Exception e) {
log.warn("项目号:" + maxProjectSubinfoCode);
}
maxCode++;
uuidLong.set(maxCode);
return projectCode +"P"+ String.format("%03d", maxCode);
}
}
} catch (InterruptedException ex) {
log.info("捕获到redission锁被打断异常", ex);
} finally {
fairLock.unlock();
}
}
return projectCode +"P"+ String.format("%03d", uuidLong.incrementAndGet());
}
});
}
redisson内部类包
package org.redisson.api;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
public interface RLock extends Lock, RLockAsync {
String getName();
void lockInterruptibly(long var1, TimeUnit var3) throws InterruptedException;
boolean tryLock(long var1, long var3, TimeUnit var5) throws InterruptedException;
void lock(long var1, TimeUnit var3);
boolean forceUnlock();
boolean isLocked();
boolean isHeldByThread(long var1);
boolean isHeldByCurrentThread();
int getHoldCount();
long remainTimeToLive();
}
package org.redisson.api;
import java.util.concurrent.TimeUnit;
import org.redisson.api.redisnode.BaseRedisNodes;
import org.redisson.api.redisnode.RedisNodes;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
public interface RedissonClient {
<V> RTimeSeries<V> getTimeSeries(String var1);
<V> RTimeSeries<V> getTimeSeries(String var1, Codec var2);
<K, V> RStream<K, V> getStream(String var1);
<K, V> RStream<K, V> getStream(String var1, Codec var2);
RRateLimiter getRateLimiter(String var1);
RBinaryStream getBinaryStream(String var1);
<V> RGeo<V> getGeo(String var1);
<V> RGeo<V> getGeo(String var1, Codec var2);
<V> RSetCache<V> getSetCache(String var1);
<V> RSetCache<V> getSetCache(String var1, Codec var2);
<K, V> RMapCache<K, V> getMapCache(String var1, Codec var2);
<K, V> RMapCache<K, V> getMapCache(String var1, Codec var2, MapOptions<K, V> var3);
<K, V> RMapCache<K, V> getMapCache(String var1);
<K, V> RMapCache<K, V> getMapCache(String var1, MapOptions<K, V> var2);
<V> RBucket<V> getBucket(String var1);
<V> RBucket<V> getBucket(String var1, Codec var2);
RBuckets getBuckets();
RBuckets getBuckets(Codec var1);
<V> RHyperLogLog<V> getHyperLogLog(String var1);
<V> RHyperLogLog<V> getHyperLogLog(String var1, Codec var2);
<V> RList<V> getList(String var1);
<V> RList<V> getList(String var1, Codec var2);
<K, V> RListMultimap<K, V> getListMultimap(String var1);
<K, V> RListMultimap<K, V> getListMultimap(String var1, Codec var2);
<K, V> RListMultimapCache<K, V> getListMultimapCache(String var1);
<K, V> RListMultimapCache<K, V> getListMultimapCache(String var1, Codec var2);
<K, V> RLocalCachedMap<K, V> getLocalCachedMap(String var1, LocalCachedMapOptions<K, V> var2);
<K, V> RLocalCachedMap<K, V> getLocalCachedMap(String var1, Codec var2, LocalCachedMapOptions<K, V> var3);
<K, V> RMap<K, V> getMap(String var1);
<K, V> RMap<K, V> getMap(String var1, MapOptions<K, V> var2);
<K, V> RMap<K, V> getMap(String var1, Codec var2);
<K, V> RMap<K, V> getMap(String var1, Codec var2, MapOptions<K, V> var3);
<K, V> RSetMultimap<K, V> getSetMultimap(String var1);
<K, V> RSetMultimap<K, V> getSetMultimap(String var1, Codec var2);
<K, V> RSetMultimapCache<K, V> getSetMultimapCache(String var1);
<K, V> RSetMultimapCache<K, V> getSetMultimapCache(String var1, Codec var2);
RSemaphore getSemaphore(String var1);
RPermitExpirableSemaphore getPermitExpirableSemaphore(String var1);
RLock getLock(String var1);
RLock getSpinLock(String var1);
RLock getSpinLock(String var1, LockOptions.BackOff var2);
RLock getMultiLock(RLock... var1);
/** @deprecated */
@Deprecated
RLock getRedLock(RLock... var1);
RLock getFairLock(String var1);
RReadWriteLock getReadWriteLock(String var1);
<V> RSet<V> getSet(String var1);
<V> RSet<V> getSet(String var1, Codec var2);
<V> RSortedSet<V> getSortedSet(String var1);
<V> RSortedSet<V> getSortedSet(String var1, Codec var2);
<V> RScoredSortedSet<V> getScoredSortedSet(String var1);
<V> RScoredSortedSet<V> getScoredSortedSet(String var1, Codec var2);
RLexSortedSet getLexSortedSet(String var1);
RTopic getTopic(String var1);
RTopic getTopic(String var1, Codec var2);
RReliableTopic getReliableTopic(String var1);
RReliableTopic getReliableTopic(String var1, Codec var2);
RPatternTopic getPatternTopic(String var1);
RPatternTopic getPatternTopic(String var1, Codec var2);
<V> RQueue<V> getQueue(String var1);
<V> RTransferQueue<V> getTransferQueue(String var1);
<V> RTransferQueue<V> getTransferQueue(String var1, Codec var2);
<V> RDelayedQueue<V> getDelayedQueue(RQueue<V> var1);
<V> RQueue<V> getQueue(String var1, Codec var2);
<V> RRingBuffer<V> getRingBuffer(String var1);
<V> RRingBuffer<V> getRingBuffer(String var1, Codec var2);
<V> RPriorityQueue<V> getPriorityQueue(String var1);
<V> RPriorityQueue<V> getPriorityQueue(String var1, Codec var2);
<V> RPriorityBlockingQueue<V> getPriorityBlockingQueue(String var1);
<V> RPriorityBlockingQueue<V> getPriorityBlockingQueue(String var1, Codec var2);
<V> RPriorityBlockingDeque<V> getPriorityBlockingDeque(String var1);
<V> RPriorityBlockingDeque<V> getPriorityBlockingDeque(String var1, Codec var2);
<V> RPriorityDeque<V> getPriorityDeque(String var1);
<V> RPriorityDeque<V> getPriorityDeque(String var1, Codec var2);
<V> RBlockingQueue<V> getBlockingQueue(String var1);
<V> RBlockingQueue<V> getBlockingQueue(String var1, Codec var2);
<V> RBoundedBlockingQueue<V> getBoundedBlockingQueue(String var1);
<V> RBoundedBlockingQueue<V> getBoundedBlockingQueue(String var1, Codec var2);
<V> RDeque<V> getDeque(String var1);
<V> RDeque<V> getDeque(String var1, Codec var2);
<V> RBlockingDeque<V> getBlockingDeque(String var1);
<V> RBlockingDeque<V> getBlockingDeque(String var1, Codec var2);
RAtomicLong getAtomicLong(String var1);
RAtomicDouble getAtomicDouble(String var1);
RLongAdder getLongAdder(String var1);
RDoubleAdder getDoubleAdder(String var1);
RCountDownLatch getCountDownLatch(String var1);
RBitSet getBitSet(String var1);
<V> RBloomFilter<V> getBloomFilter(String var1);
<V> RBloomFilter<V> getBloomFilter(String var1, Codec var2);
RIdGenerator getIdGenerator(String var1);
RFunction getFunction();
RFunction getFunction(Codec var1);
RScript getScript();
RScript getScript(Codec var1);
RScheduledExecutorService getExecutorService(String var1);
RScheduledExecutorService getExecutorService(String var1, ExecutorOptions var2);
RScheduledExecutorService getExecutorService(String var1, Codec var2);
RScheduledExecutorService getExecutorService(String var1, Codec var2, ExecutorOptions var3);
RRemoteService getRemoteService();
RRemoteService getRemoteService(Codec var1);
RRemoteService getRemoteService(String var1);
RRemoteService getRemoteService(String var1, Codec var2);
RTransaction createTransaction(TransactionOptions var1);
RBatch createBatch(BatchOptions var1);
RBatch createBatch();
RKeys getKeys();
RLiveObjectService getLiveObjectService();
RedissonRxClient rxJava();
RedissonReactiveClient reactive();
void shutdown();
void shutdown(long var1, long var3, TimeUnit var5);
Config getConfig();
<T extends BaseRedisNodes> T getRedisNodes(RedisNodes<T> var1);
/** @deprecated */
@Deprecated
NodesGroup<Node> getNodesGroup();
/** @deprecated */
@Deprecated
ClusterNodesGroup getClusterNodesGroup();
boolean isShutdown();
boolean isShuttingDown();
String getId();
}
public interface UUIDStorage {
String generate(RedisAtomicLong uuidLong);
}
@Component("defaultUUIDStorage")
public class DefaultUUIDStorage implements UUIDStorage {
@Override
public String generate(RedisAtomicLong uuidLong) {
return uuidLong == null ? null : uuidLong.incrementAndGet()+"";
}
}