• 全局唯一ID


    1. 订单号

    订单号在业务系统中必不可取,往往需要具备:

    1. 全局唯一  2. 方便传播 (因为往往需要根据订单号来查问题)

    那么其关键怎么来保证 订单号的全局唯一呢 ? 本文只记录工作中见识到的线上运行方案。

    2. 全局唯一ID

    1. 利用db的方式 

    该方式需要DBA提前生成好一批订单号,然后将订单号分发给各个业务线,各个业务线有专门的 orderiddb 来存储这些订单号

    这样业务线只需要取这些订单号即可,怎么保证在获取的时候 不会重复获取到同一个订单号呢?  需要设计3张表 ,具体方案如下

    Table: cglobalunifiedorderid (种子-订单表)

    Field Type Comment
    SeedID bigint(20) 种子ID(主键)
    OrderID bigint(20) 订单号
    ChannelType varchar(10)  渠道
    SubType varchar(10)  子类型
    DataChange_LastTime datetime 修改

    Table : orderidseed (种子表)

    Field Type Comment
    SeedID bigint(20) 种子ID(主键)
    DataChange_LastTime datetime 修改

    Table: cunifiedorderhistory (历史订单ID表)

    Field Type Comment
    OrderID bigint(20) 订单号
    DataChange_LastTime datetime 修改时间

    其中 种子订单表 的orderid 表存储DBA分发的订单号

    取订单号CODE如下:

           private static object lockGenerateOrderID = new object();
            /// <summary>
            /// 生成订单号
            /// </summary>
            /// <returns></returns>
            public long GenerateOrderID()
            {
                long orderID = 0;
                long seedId = 0;
    
                lock (lockGenerateOrderID)
                {
                    seedId = GenerateOrderIdSeed();
                    if (seedId <= 0)
                    {
                        LogHelper.LogSOAInfo("GenerateOrderID", "未生成OrderIdSeed");
                        return 0;
                    }
    
                    orderID = QueryOrderId(seedId);
                    if (orderID > 0)
                    {
                        InsertOrderIdHistory(orderID);
                    }
                    else
                    {
                        LogHelper.LogSOAInfo("GenerateOrderID", string.Format("根据OrderIdSeed:{0} 未获取到OrderID", seedId));
                    }
                }
    
                return orderID;
            }
    
            private long GenerateOrderIdSeed()
            {
                var result = baseDao_W.ExecScalar("INSERT INTO orderidseed(DataChange_LastTime) VALUES(NOW());SELECT LAST_INSERT_ID();");
                if (result == null)
                    return 0;
    
                return TypeUtil.ToInt64(result);
            }
    
            private void InsertOrderIdHistory(long orderId)
            {
                string sql = "INSERT INTO cunifiedorderhistory (OrderID)VALUES(@orderId)";
                StatementParameterCollection para = new StatementParameterCollection();
                para.AddInParameter("@orderId", DbType.Int64, orderId);
                baseDao_W.ExecNonQuery(sql, para);
            }
    
            private long QueryOrderId(long seedId)
            {
                string sql = "SELECT OrderID FROM cglobalunifiedorderid WHERE SeedID=@seedId";
                StatementParameterCollection para = new StatementParameterCollection();
                para.AddInParameter("@seedId", DbType.Int64, seedId);
    
                DataTable dt = baseDao_W.SelectDataTable(sql, para);
    
                if (dt == null || dt.Rows == null || dt.Rows.Count == 0)
                    return 0;
    
                return TypeUtil.ToInt64(dt.Rows[0]["OrderID"]);
            }

    当然分布式系统下,业内还有其他方案来生成全局唯一ID,以后研究的时候会在做记录。

    六度与心 修行苦 苦修行
  • 相关阅读:
    long类型的数据转化为时间
    取到数组中对应位置的文字,并且转成大写
    无key值的json数组解析
    mongo-2ds索引对超过半球范围的适用性测试
    mongoDB-Cannot change the size of a document in a capped collection:
    springboot
    左中右布局的五种实现方式
    spring boot 常见的配置问题
    移动端H5拍照代码实现及外网部署
    JAVA数据库操作回滚小结
  • 原文地址:https://www.cnblogs.com/hdtechnology/p/9383709.html
Copyright © 2020-2023  润新知