//redission 客户端@Component
public class RedisUUID {@Autowiredprivate 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;}
}
应用案例:
@Overridepublic String generateCode(Long projectId) {final String projectCode = projectSubinfoMapper.selectProjectCodeById(projectId);return redisUUID.generateUUID("pms:projectsubinfo:projectsubinfo:code:" + projectCode, null, null, new UUIDStorage() {@Overridepublic 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 */@DeprecatedRLock 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 */@DeprecatedNodesGroup<Node> getNodesGroup();/** @deprecated */@DeprecatedClusterNodesGroup getClusterNodesGroup();boolean isShutdown();boolean isShuttingDown();String getId();
}
public interface UUIDStorage {String generate(RedisAtomicLong uuidLong);
}
@Component("defaultUUIDStorage")
public class DefaultUUIDStorage implements UUIDStorage {@Overridepublic String generate(RedisAtomicLong uuidLong) {return uuidLong == null ? null : uuidLong.incrementAndGet()+"";}
}