分布式系統電商訂單號的最佳生成方式


最近在研發區塊鏈支付系統,眾所周知,有支付必有訂單。今天不做支付系統的具體分析,只來談談目前較為熱門的訂單號碼生成方案!

在分布式高並發情況下,訂單號必須滿足最重要的一個條件:唯一性,訂單關系這支付明細,與支付相關的向來都是最重要的,馬虎不得。

目前較為成熟的,我所知道的有兩種生成方案,接下來做一下對比:

1、根據MySQL自增主鍵生成訂單號

首先,需要創建一張滿足自增條件的表,有兩個字段即可,id和value,id設置為自增,類型為bigint即可

eg:在mybatis框架中

<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="id" parameterType="com.chenzhou.mybatis.User">
    insert into user(userName,password,comment)
    values(#{userName},#{password},#{comment})
</insert>

其中useGeneratedKeys="true" 的配置就表示新增后返回主鍵id,此時我們就可以根據主鍵id做訂單唯一性標識,再加上時間201903010+自增主鍵,或其他復雜的組合方式即可

此方式的優點:關系型數據庫的可靠性!

此方式的缺點:在分布式環境下,需要保證新增的操作是單線程的,需要加鎖。

 

2、利用Redis非關系型數據庫

先看代碼,再解釋

 public String getOrderId(String prefix) {
        //生成訂單號 redis incr
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String time = sdf.format(new Date());
        //當天流水7位
        Long tx = redisTemplate.opsForValue().increment(CommonConstants.OUR_ORDER_ID_INCREMENT_KEY, 1);
        if (tx < CommonConstants.ORDER_ID_INCREMENT_DEFAULT_VALUE) {
            //沒值,自動添加
            redisTemplate.opsForValue().set(CommonConstants.OUR_ORDER_ID_INCREMENT_KEY, CommonConstants.ORDER_ID_INCREMENT_DEFAULT_VALUE);
            tx = redisTemplate.opsForValue().increment(CommonConstants.OUR_ORDER_ID_INCREMENT_KEY, 1);
        }
        //自動補0
        String end = autoAddZero(String.valueOf(tx));
        return prefix + time + end;
    }


    public String autoAddZero(String liuShuiHao) {
        Integer intHao = Integer.parseInt(liuShuiHao);
        DecimalFormat df = new DecimalFormat(CommonConstants.ORDER_ID_NUM);
        return df.format(intHao);
    }
getOrderId方法,傳入參數prefix,這是訂單前綴,有時候我們需要為不同種類或功能生成不一樣的訂單前綴以助區分,其中最主要是用到了redis的incr函數。我們都知道redis是單行程的,每次操作都不會引發臟讀的問題
因此,我們可以利用redis的自增方法incr為我們的訂單做唯一性處理。
tx < CommonConstants.ORDER_ID_INCREMENT_DEFAULT_VALUE 的判斷是由於第一次調用是沒有值的,需要設置一個初始值

autoAddZero是我寫的輔助保持訂單長度一致的方法,剩下的大寫的都是常量,根據字面意思設置即可

此方法的優點:基於緩存策略的性能上明顯提升。
此方法的缺點:redis數據需要載入硬盤,防丟失(其實也不算缺點)

如有不妥,歡迎指正!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM