美文网首页
订单号:生成指定前缀日期流水号;redis分布式

订单号:生成指定前缀日期流水号;redis分布式

作者: 一个忙来无聊的人 | 来源:发表于2023-01-05 11:02 被阅读0次

    流水号生成、分布式

    SpringUtil:获取对象用,其他都在注释里面

    public class OrderNoUtil {
    
        /**
         * 时间格式化
         */
        private final static String DATE_STR = "yyyyMMdd";
    
        /**
         * 占位前缀
         */
        private final static String PLACE_HOLDER = "00000000000";
    
        /**
         * 订单号生成工具类
         * @param prefix       前缀
         * @param size 流水号位数   最大支持12位,如果不满足需求可以把占位前缀加大
         * @param maxValue  如果redis没有做持久化,redis重启,需要传递最大值
         * @return
         */
        public static String buildOrderNO(String prefix, Integer size, Long maxValue) {
            // 获取redis
            RedisClient redisClient = SpringUtil.getBean(RedisClient.class);
            // 生成前缀  此处为 入参前缀 + 日期 (20230106)
            String keyPreFix = prefix + DateUtil.format(new Date(), DATE_STR);
            if (maxValue != null){
                synchronized (keyPreFix) {
                    // 设置redis值为传递的最大值,并且过期时间为24小时
                    Long value = redisClient.get(keyPreFix);
                    if (value == null || maxValue > value){
                        redisClient.setEx(keyPreFix, maxValue, Duration.ofHours(24L));
                    }
                }
            }else {
                if (!redisClient.exists(keyPreFix)){
                    synchronized (keyPreFix){
                        if (!redisClient.exists(keyPreFix)){
                            redisClient.setEx(keyPreFix, 0, Duration.ofHours(24L));
                        }
                    }
                }
            }
            // 利用redis自增方法,增加
            Long value = redisClient.incr(keyPreFix);
            String valueStr = PLACE_HOLDER + value;
            return keyPreFix + valueStr.substring(valueStr.length() - size);
        }
    }
    

    以上仅为个人愚见,如果有更好方案,欢迎大家指出

    相关文章

      网友评论

          本文标题:订单号:生成指定前缀日期流水号;redis分布式

          本文链接:https://www.haomeiwen.com/subject/iqzdcdtx.html