ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

记一次订单号事故

2021-05-20 16:03:28  阅读:170  来源: 互联网

标签:一次 String 事故 IP 订单数 orderNos 订单号 static size


经手的同事之前也改过几次,不过效果始终不好:总会出现订单号重复的问题,
所以趁着这次问题我好好的理了一下我同事写的代码。

这里简要展示下当时的代码:

/**
       * OD单号生成
       * 订单号生成规则:OD + yyMMddHHmmssSSS + 5位数(商户ID3位+随机数2位) 22位
       */
      public static String getYYMMDDHHNumber(String merchId){
          StringBuffer orderNo = new StringBuffer(new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()));
          if(StringUtils.isNotBlank(merchId)){
              if(merchId.length()>3){
                  orderNo.append(merchId.substring(0,3));
              }else {
                  orderNo.append(merchId);
              }
          }
          int orderLength = orderNo.toString().length();
          String randomNum = getRandomByLength(20-orderLength);
          orderNo.append(randomNum);
          return orderNo.toString();
      }
  
  
      /** 生成指定位数的随机数 **/
      public static String getRandomByLength(int size){
          if(size>8 || size<1){
              return "";
          }
          Random ne = new Random();
          StringBuffer endNumStr = new StringBuffer("1");
          StringBuffer staNumStr = new StringBuffer("9");
          for(int i=1;i<size;i++){
              endNumStr.append("0");
              staNumStr.append("0");
          }
          int randomNum = ne.nextInt(Integer.valueOf(staNumStr.toString()))+Integer.valueOf(endNumStr.toString());
          return String.valueOf(randomNum);
      }

可以看到,这段代码写的其实不怎么好,代码部分暂且不议,代码中使订单号不重复的主要因素点是随机数和毫秒,可是这里的随机数只有两位
在高并发环境下极容易出现重复问题,同时毫秒这一选择也不是很好,在多核CPU多线程下,一定时间内(极小的)这个毫秒可以说是固定不变的(测试验证过),所
以这里我先以100个并发测试下这个订单号生成,测试代码如下:

public static void main(String[] args) {
        final String merchId = "12334";
        List<String> orderNos = Collections.synchronizedList(new ArrayList<String>());
        IntStream.range(0,100).parallel().forEach(i->{
            orderNos.add(getYYMMDDHHNumber(merchId));
        });

        List<String> filterOrderNos = orderNos.stream().distinct().collect(Collectors.toList());

        System.out.println("生成订单数:"+orderNos.size());
        System.out.println("过滤重复后订单数:"+filterOrderNos.size());
        System.out.println("重复订单数:"+(orderNos.size()-filterOrderNos.size()));
    }

果然,测试的结果如下:

生成订单数:100
过滤重复后订单数:87
重复订单数:13

当时我就震惊

标签:一次,String,事故,IP,订单数,orderNos,订单号,static,size
来源: https://www.cnblogs.com/edda/p/14790080.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有