zoukankan      html  css  js  c++  java
  • 全局唯一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,以后研究的时候会在做记录。

    六度与心 修行苦 苦修行
  • 相关阅读:
    C#面向对象的基本原则
    EXTJS学习笔记:类似于Window的登录窗体
    c# 类似于QQ表情弹出框功能的二种实现方法
    EXTJS学习笔记:grid之分组实现groupingview
    RibbonBar屏蔽右键
    webservice安全性浅谈
    js生成二维码以及插入图片
    c++之const解惑
    最短路径连接表形式
    深入理解c++之动态内存和指针
  • 原文地址:https://www.cnblogs.com/hdtechnology/p/9383709.html
Copyright © 2011-2022 走看看