Redission分布式锁应用案例(生成业务单号)

embedded/2024/9/23 0:32:28/
//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()+"";}
}


http://www.ppmy.cn/embedded/13219.html

相关文章

Python爬取猫眼电影票房 + 数据可视化

目录 主角查看与分析 爬取可视化分析猫眼电影上座率前10分析猫眼电影票房场均人次前10分析猫眼电影票票房占比分析 主角查看与分析 爬取 对猫眼电影票房进行爬取&#xff0c;首先我们打开猫眼 接着我们想要进行数据抓包&#xff0c;就要看网站的具体内容&#xff0c;通过按F12…

主打国产算力 广州市通用人工智能公共算力中心项目签约

4月9日&#xff0c;第十届广州国际投资年会期间&#xff0c;企商在线&#xff08;北京&#xff09;数据技术股份有限公司与广州市增城区政府就“广州市通用人工智能公共算力中心”项目进行签约。 该项目由广州市增城区人民政府发起&#xff0c;企商在线承建。项目拟建成中国最…

程序员过了35岁没人要?“这行越老越香”

程序员35岁失业&#xff1f;参加完OceanBase开发者大会&#xff0c;我又悟了&#xff01; 周六参加了OceanBase2024 开发者大会的现场&#xff0c;来之前我其实挺忐忑的&#xff0c;我觉得一个数据库产品的发布会&#xff0c;能有什么新鲜的东西&#xff1f; 踏入酒店的那一刻&…

SQL-DML数据操纵语言(Oracle)

文章目录 DML数据操纵语言常见的字段属性字符型字段属性char(n)varchar2(n)/varchar(n) 数值型字段属性number([p],[s]int 日期型字段属性DATEtimestamp 如何查看字段属性增加数据INSERT快捷插入 删除数据DELETE修改数据UPDATE DML数据操纵语言 定义 是针对数据做处理&#xf…

Vue2学习笔记(尚硅谷天禹老师)

目录 一、入门案例 二、模板语法 三、数据绑定 四、el和data的两种写法 五、MVVM模型 六、Object.defineproperty方法 七、Vue中响应式原理 八、数据代理 九、methods配置项 十、Vue中的事件处理 十一、Vue中的键盘事件 十二、计算属性 十三、监视属性watch 十四、绑定Class样式…

XxlJob外网访问

Xxl-Job使用外网访问 服务注册中心配置 ### web server.port8088 server.servlet.context-path/xxl-job-admin### actuator management.server.base-path/actuator management.health.mail.enabledfalse### resources spring.mvc.servlet.load-on-startup0 spring.mvc.static…

liteide 找不到 go 路径错误修复

在配置文件&#xff1a;C:\Users\iwlb\AppData\Roaming\liteide\liteide.ini中修改 [liteenv] currentenvidwin64 改为 [liteenv] currentenvidsystem 启动脚本: set GO111MODULEoff set GOROOTM:\work\tool\go1.21.2.windows-amd64 set GOPATHM:\work\code\go set PATHM:\…

第 394 场 LeetCode 周赛题解

A 统计特殊字母的数量 I 哈希&#xff1a;遍历然后枚举 class Solution {public:int numberOfSpecialChars(string word) {unordered_map<char, int> m;for (auto ch : word)m[ch] 1;int res 0;for (char ch a; ch < z; ch)if (m.count(ch) && m.count(A …