newxhy 发表于 2009-2-12 09:00:25

如何生成连续的流水号

工作中常常遇到流水号生成的问题,有的客户要求流水号必须连续,这个我们的开发工作提出了一个小难题。
    解决方法如下:
    方法一:采用最大号表的形式
    在数据库中创建一个表专门存放其他数据库的最大流水号,table_maxOrderID{table1_max,table2_max};
    在向数据库中插入数据的时候,首先想table_maxOrderId表查询到当前表的最大号加1,先更新最大号表,然后保存到业务数据。
    优点:效率高
    缺点:号码浪费大一些(例如保存的时候失败了,那么这个号码就浪费了。)
   
    方法二:采用抢号的形式
    这个不需要创建最大号表,在向数据库中保存数据的时候,获取当前表的最大流水号。例如:
    select max(ID) from tableName ;让后将结果加一。
    优点:速度快,不浪费号码;
    缺点:并发的时候,号码重复造成数据无法保存。
    解决办法:抢号。如果保存失败,那么重复抢号例如:
    public synchronized String getOrderId(String shengid) {
      if (shengid == null || "".equals(shengid.trim())) {
            throw new NullPointerException("在获取流水号的时候,省id为空!获取流水号失败!");
      }
      // 首先查找所在地区查找企业表中有没有数据
      int num = xjqyDao.getCountBySql(" and qy_sheng='"   shengid   "'");
      String orderId = null;
      if (num == 0) {
            orderId = "0001";
      } else {
            //必须找到本省最大的档案的id
            String maxDabh = xjqyDao.getMaxDabhBySheng(shengid);
            num = Integer.parseInt(maxDabh.substring(6));
            String temp = (num   1)   "";
            int LEN = temp.length();
            if (LEN > 4) {
                log.error("出错了!一个省的蚕茧收购加工企业的个数不能超过1万!");
                return null;
            }
            for (int i = 0; i < 4 - LEN; i) {
                temp = "0"   temp;
            }
   
   
                  
            orderId = temp;
      }
      return orderId;
    }
    <PRE class=java name="code">            for (int i = 0; i < 5; i) { // 连续抢号5次,如果失败,请用户稍后再试!
                  try {
                        String orderId = getOrderId(xjqy.getSheng());// 获取连续的流水号
                        log.debug("获取到的连续的流水号为:"   orderId);
                        String dabh = ""; // 档案编号
                        String code = ""; // 企业编号
   
                        dabh = xjqy.getSheng()   xjqy.getJdrq().substring(0, 4)
                                  orderId;
                        log.debug("档案编号为:"   dabh);
                        xjqy.setDabh(dabh);
   
                        // 所在省做了js校验
                        if (xjqy.getShi() == null || xjqy.getShi().equals("")) {
                            // 如果市为空
                            code = xjqy.getSheng()   "0000"   xjqy.getLb()
                                    orderId;
                        } else if (xjqy.getXian() == null
                              || xjqy.getXian().equals("")) {
                            // 如果县为空
                            code = xjqy.getShi()   "00"   xjqy.getLb()   orderId;
                        } else {
                            code = xjqy.getXian()   xjqy.getLb()   orderId;
                        }
                        log.debug("企业编号为:"   code);
                        xjqy.setCode(code);
   
                        xjqyDao.create(xjqy);
                        log.debug("create object");
                        flag = true;// 保存成功!
                        break; // 退出循环
                  } catch (Exception e) {
                        log.debug("保存企业信息出错:", e);
                  }
                }
   
                if (!flag) {
                  throw new OurException("保存失败!请稍后重试!");
                }</PRE>
   
上一页    
                  
    view plaincopy to clipboardprint?for (int i = 0; i < 5; i) { // 连续抢号5次,如果失败,请用户稍后再试!         try {
             String orderId = getOrderId(xjqy.getSheng());// 获取连续的流水号
             log.debug("获取到的连续的流水号为:"   orderId);
             String dabh = ""; // 档案编号
             String code = ""; // 企业编号
               dabh = xjqy.getSheng()   xjqy.getJdrq().substring(0, 4)
                     orderId;
             log.debug("档案编号为:"   dabh);
             xjqy.setDabh(dabh);
               // 所在省做了js校验
             if (xjqy.getShi() == null || xjqy.getShi().equals("")) {
               // 如果市为空
               code = xjqy.getSheng()   "0000"   xjqy.getLb()
                           orderId;
             } else if (xjqy.getXian() == null
                  || xjqy.getXian().equals("")) {
               // 如果县为空
               code = xjqy.getShi()   "00"   xjqy.getLb()   orderId;
             } else {
               code = xjqy.getXian()   xjqy.getLb()   orderId;
             }
             log.debug("企业编号为:"   code);
             xjqy.setCode(code);
               xjqyDao.create(xjqy);
             log.debug("create object");
             flag = true;// 保存成功!
             break; // 退出循环
         } catch (Exception e) {
             log.debug("保存企业信息出错:", e);
         }
   }
         if (!flag) {
         throw new OurException("保存失败!请稍后重试!");
   }
   for (int i = 0; i < 5; i) { // 连续抢号5次,如果失败,请用户稍后再试!
      try {
         String orderId = getOrderId(xjqy.getSheng());// 获取连续的流水号
         log.debug("获取到的连续的流水号为:"   orderId);
         String dabh = ""; // 档案编号
         String code = ""; // 企业编号
   
         dabh = xjqy.getSheng()   xjqy.getJdrq().substring(0, 4)
             orderId;
         log.debug("档案编号为:"   dabh);
         xjqy.setDabh(dabh);
   
         // 所在省做了js校验
         if (xjqy.getShi() == null || xjqy.getShi().equals("")) {
          // 如果市为空
          code = xjqy.getSheng()   "0000"   xjqy.getLb()
            orderId;
         } else if (xjqy.getXian() == null
         || xjqy.getXian().equals("")) {
          // 如果县为空
          code = xjqy.getShi()   "00"   xjqy.getLb()   orderId;
         } else {
          code = xjqy.getXian()   xjqy.getLb()   orderId;
         }
         log.debug("企业编号为:"   code);
         xjqy.setCode(code);
   
         xjqyDao.create(xjqy);
         log.debug("create object");
         flag = true;// 保存成功!
         break; // 退出循环
      } catch (Exception e) {
         log.debug("保存企业信息出错:", e);
      }
       }
   
       if (!flag) {
      throw new OurException("保存失败!请稍后重试!");
       }
    小结:
    如果要从严格意义上生成连续的流水号,那么应该采用抢号的方法,同时限制用户不准删除记录,这样才能保证流水号的严格 连续,否则录入5条,删掉其中的2条,那么用户看到的记录的号码将无法连续了。
   上一页
页: [1]
查看完整版本: 如何生成连续的流水号