最近幾年,我一直從事的是運營平臺業務開發。每天,我們都需要處理大量的工單配置工作。為了生成工單號,我們建立了一張專用的數據庫表,用于記錄和生成工單號。每次創建工單時,我們會查詢這張表,根據年份字段、月份字段和模塊編碼找到最大的自增序列號。隨后,我們將自增序列號加一,與模塊編碼、年月序列號拼接以生成工單號,并將相關信息寫入表中。這種方法一直使用得很順利,因為工單配置的量并不是特別大,一直都沒有出現問題。然而,最近我們為第三方提供了一個工單推送的接口,他們一次性推送了大量的工單,這導致不僅生成了許多重復工單號,而且還引起了接口性能方面的問題。因此,我們決定對工單號生成方式進行改進,本文我們將介紹下我們新的生成方法。
這次我們采用了 Redisson 的 RAtomicLong 來生成一個以固定字符加上年月為鍵的自增數。隨后,將自增數轉換為36進制字符串,以年月和36進制字符串拼接形成全局唯一的工單號。
SerialIdService.java
@Service@Slf4jpublic class SerialIdService { private static final String ID_KEY = "xiuji:"; private static final int BASE_36 = 36; private static final Integer SEQUENCE_LENGTH = 5; @Resource private RedissonClient redissonClient; public String workSerialId() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMM"); String dateStr = LocalDate.now().format(formatter); //使用了Redisson的AtomicLong對象生成唯一序列號 RAtomicLong atomicLong = redissonClient.getAtomicLong(ID_KEY+dateStr); //設置過期時間為35天 if(atomicLong.get() == 0){ atomicLong.expire(Duration.ofDays(35)); } //將唯一序列號轉換為36進制的字符串,長度為4位,用于減少ID的長度 String sequenceStr = Long.toString(atomicLong.incrementAndGet(), BASE_36).toUpperCase(); //36進制的序列號若小于4位,則用0補齊高位 if (sequenceStr.length() < SEQUENCE_LENGTH) { sequenceStr = String.format("%4s", sequenceStr).replace(' ', '0');; } String serialId = dateStr+sequenceStr; log.info("生成的工單號:{}",dateStr+sequenceStr); return dateStr+sequenceStr; }}
生成的工單號示例:
240121AXT6240121AXT7240121AXT8240121AXT9240121AXTA240121AXTB240121AXTC240121AXTD240121AXTE240121AXTF240121AXTG240121AXTH240121AXTI240121AXTJ
通過Redisson的RAtomicLong,我們成功實現了一個簡單而強大的全局唯一工單號生成器。該生成器保證了唯一性,且在分布式環境中表現出色。在實際應用中,可以根據業務需求進行調整和擴展,以滿足更復雜的場景。
本文鏈接:http://www.www897cc.com/showinfo-26-68323-0.html基于Redisson的RAtomicLong實現全局唯一工單號生成器
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: JDK17 與 JDK11 特性差異淺談