高并發下怎樣生成唯一的訂單號?
作者:conan5566
一個軟件系統,肯定到處充滿著各種單據,也必然需要有各種單據號與之對應。比如:電商行業的訂單號、支付流水號、退款單號等等。
本文轉載自微信公眾號「UP技術控」,作者conan5566。轉載本文請聯系UP技術控公眾號。
一個軟件系統,肯定到處充滿著各種單據,也必然需要有各種單據號與之對應。比如:電商行業的訂單號、支付流水號、退款單號等等。SCM的采購單號、進貨單號、出貨單號、盤點單號等。在一個企業內部或者一個2C的平臺,無法避免的需要通過某個單據號來進行溝通。所以一個好的單據號必然是便于溝通的。那么如何創建全局唯一的單據號。
1、單系統使用object
- /// <summary>
- /// 單號助手
- /// </summary>
- public class BillNoHelper
- {
- /// <summary>
- /// 防止創建類的實例
- /// </summary>
- private BillNoHelper() { }
- private static readonly object locker = new object();
- private static int _sn = 0;
- /// <summary>
- /// 生成單據編號
- /// </summary>
- /// <returns></returns>
- public static string GenerateId()
- {
- lock (locker) //lock 關鍵字可確保當一個線程位于代碼的臨界區時,另一個線程不會進入該臨界區。
- {
- if (_sn == 9999)
- {
- _sn = 1;
- }
- else
- {
- _sn++;
- }
- return DateTime.Now.ToString("yyMMddHHmmss") + _sn.ToString().PadLeft(4, '0');
- }
- }
- /// <summary>
- /// 唯一值
- /// </summary>
- /// <returns></returns>
- public static string guid()
- {
- return Guid.NewGuid().ToString().Replace("-", "");
- }
- /// <summary>
- /// GuidExtension
- /// </summary>
- /// <param name="guid"></param>
- /// <returns></returns>
- public static string IsNum(Guid guid)
- {
- var s = guid.ToString();
- var sb = new StringBuilder();
- for (int i = 0; i < s.Length; i++)
- {
- if (Char.IsNumber(s, i))
- {
- sb.Append(s.Substring(i, 1));
- }
- }
- return sb.ToString();
- }
- #region 生成 Coupon Key
- private static readonly object locker2 = new object();
- private static int _sn2 = 0;
- /// <summary>
- /// 生成key 12位 字母+數字
- /// </summary>
- /// <returns></returns>
- public static string GenerateCouponKey()//
- {
- string s;
- lock (locker2)
- {
- if (_sn2 == 9999999)
- {
- _sn2 = 1;
- }
- else
- {
- _sn2++;
- }
- s = $"Qq@,.*745u787#$@,.><;'{DateTime.Now.Ticks}{_sn2}";
- }
- return MD5_16(s);
- }
- private static string MD5_16(string p_str)
- {
- System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
- byte[] data = System.Text.Encoding.Default.GetBytes(p_str);
- byte[] md5Data = md5.ComputeHash(data);
- string strResult = System.BitConverter.ToString(md5Data, 4, 8);
- md5.Clear();
- strResult = strResult.Replace("-", "").ToUpper();
- return strResult;
- }
- #endregion
- }
2、數據唯一索引
利用數據庫索引的特性生成唯一id.
3、使用redis分布式鎖
在同一時間只會有一個客戶端能獲取到鎖,其它客戶端無法同時獲取,這把鎖在一段有限的時間之后,一定會被釋放(正常釋放或異常釋放)。
責任編輯:武曉燕
來源:
UP技術控