zoukankan      html  css  js  c++  java
  • 通过存储过程解决并发生成唯一订单号

    DELIMITER $$
     
    USE `roamerbuddy`$$
     
    DROP PROCEDURE IF EXISTS `generate_orderNo`$$
     
    CREATE DEFINER=`root`@`%` PROCEDURE `generate_orderNo`(
      IN orderNamePre CHAR(4),
      IN num INT,
      OUT newOrderNo VARCHAR (25)
    )
    BEGIN
      -- 订单变化的值
      DECLARE orderNameValue INT ;
      -- 更新行数
      DECLARE updateRow INT ;
      -- 当前日期,有可能包含时分秒  
      DECLARE currentTime DATETIME ;
      -- 订单号   
      DECLARE orderCode VARCHAR (64) ;
      -- 异常处理
      DECLARE CONTINUE HANDLER FOR 1062
      SET currentTime = NOW() ;
      
      SELECT 
        IFNULL(gs.ordervalue, 0) INTO orderNameValue 
      FROM
        generate_serialno gs 
      WHERE id = 1 ;
      
      SET currentTime = NOW() ;
     
      -- 打开自动提交
      SET autocommit = 1 ;
      IF TRUE 
      THEN 
      INSERT INTO generate_serialno (id, ordervalue, ordertime) 
      VALUES
        (1, 1, currentTime) ;
      END IF ;
      UPDATE 
        generate_serialno obj 
      SET
        obj.ordervalue = 
        CASE
          WHEN TO_DAYS(currentTime) > TO_DAYS(obj.ordertime) 
          THEN 1 
          ELSE orderNameValue + 1 
        END,
        obj.ordertime = currentTime 
      WHERE (
          obj.id = 1 
          AND obj.ordervalue = orderNameValue
        ) ;
      SET updateRow = ROW_COUNT() ;
      WHILE
        ! updateRow = 1 DO -- 获得当前的订单和变化的值   
        SELECT 
          IFNULL(gs.ordervalue, 0) INTO orderNameValue 
        FROM
          generate_serialno gs 
        WHERE id = 1 ;
        UPDATE 
          generate_serialno obj 
        SET
          obj.ordervalue = 
          CASE
            WHEN TO_DAYS(currentTime) > TO_DAYS(obj.ordertime) 
            THEN 1 
            ELSE orderNameValue + 1 
          END,
          obj.ordertime = currentTime 
        WHERE (
            obj.id = 1 
            AND obj.ordervalue = orderNameValue
          ) ;
        SET updateRow = ROW_COUNT() ;
      END WHILE ;
      IF num = 8 
      THEN -- 根据年月日生成订单编号,订单编号形式:前缀+年月日+流水号,如:SH2013011000002     
      SELECT 
        CONCAT(
          orderNamePre,
          DATE_FORMAT(currentTime, '%Y%m%d'),
          LPAD(orderNameValue, num, '0')
        ) INTO orderCode ;
      ELSEIF num = 14 
      THEN -- 根据年月日时分秒生成订单编号,订单编号形式:前缀+年月日时分秒+流水号,如:SH2013011010050700001,个人不推荐使用这种方法生成流水号     
      SELECT 
        CONCAT(
          orderNamePre,
          DATE_FORMAT(currentTime, '%Y%m%d%H%i%s'),
          LPAD(orderNameValue, num, '0')
        ) INTO orderCode ;
      ELSE -- 根据年月日时分生成订单编号,订单形式:前缀+年月日时分+流水号,如:SH20130110100900005
      SELECT 
        CONCAT(
          orderNamePre,
          DATE_FORMAT(currentTime, '%Y%m%d%H%i'),
          LPAD(orderNameValue, num, '0')
        ) INTO orderCode ;
      END IF ;
      SELECT 
        orderCode ;
    END$$
     
    DELIMITER ;
    DROP TABLE IF EXISTS `generate_serialno`;
     
    CREATE TABLE `generate_serialno` (
      `id` int(20) DEFAULT NULL,
      `orderno` varchar(50) DEFAULT NULL,
      `orderpre` varchar(30) DEFAULT NULL,
      `ordervalue` int(20) DEFAULT NULL,
      `ordertime` datetime DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    insert into `generate_serialno` (`id`, `ordervalue`) values('1','1');
  • 相关阅读:
    多线程
    IO
    Collections工具类
    File类
    Map
    List与Set接口
    如何把数学作为一种工具
    包装类
    异常
    内部类
  • 原文地址:https://www.cnblogs.com/insane-Mr-Li/p/10103298.html
Copyright © 2011-2022 走看看