memcached 高并發(fā),流水號(hào)生成方案

流水號(hào)作為唯一編號(hào),在銀行以及財(cái)務(wù)業(yè)務(wù)系統(tǒng)中尤為常見。
在設(shè)計(jì)中一般采用年、月、日等遞增方式,列如:2018012200001,表示2018年1月22日的第一個(gè)編號(hào)。

傳統(tǒng)的處理方式

常見數(shù)據(jù)庫遞增不能按年、月、日格式生成遞增編號(hào),不過可以通過其他方式實(shí)現(xiàn),如在 MSSQL 數(shù)據(jù)庫中可以采用觸發(fā)、自定義函數(shù)實(shí)現(xiàn)。

新建一個(gè)表 Order,必須擁有以下三個(gè)字段

名稱 類型 說明
Code nvarchar(32) 用于存儲(chǔ)完整的流水號(hào)
Seed bigint 種子值,考慮大數(shù)據(jù)量的情況采用 bigint 類型
Date datetime 當(dāng)前時(shí)間

觸發(fā)器代碼創(chuàng)建

IF (OBJECT_ID('TGR_Order_INSERT', 'TR') IS NOT NULL) DROP TRIGGER TGR_Order_INSERT
GO
CREATE TRIGGER TGR_Order_INSERT ON Order FOR INSERT
AS
BEGIN
    BEGIN tran
    DECLARE @OrderID UNIQUEIDENTIFIER, @Seed BIGINT
    SET @Seed = ISNULL((SELECT MAX(Seed) FROM Order WITH (TABLOCK, HOLDLOCK) WHERE DATEDIFF(DAY, Date, GETDATE()) = 0 AND Seed > 0), CAST(CONVERT(NVARCHAR(8), GETDATE(), 112) + N'0000000000' AS BIGINT)) -- 取得當(dāng)前最大一個(gè)流水號(hào)種子,如果不存在使用默認(rèn)值
    DECLARE OrderCursor CURSOR FOR SELECT OrderID FROM INSERTED
    OPEN OrderCursor
    FETCH NEXT FROM OrderCursor INTO @OrderID
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @Seed = @Seed + 1 --遞增種子號(hào)
        UPDATE Order SET Seed = @Seed, Code = CAST(@Seed AS NVARCHAR(18)) WHERE OrderID = @OrderID  
        FETCH NEXT FROM OrderCursor INTO @OrderID
    END  
    CLOSE OrderCursor    
    DEALLOCATE OrderCursor
    COMMIT tran
END
GO
  1. 注意該觸發(fā)使用了游標(biāo),為了保證數(shù)據(jù)計(jì)算的準(zhǔn)確性進(jìn)行鎖表操作。
  2. 稍作修改即可改為自定義函數(shù),這里我就不再寫出自定義函數(shù)的創(chuàng)建。
  3. 可以見得這種方式在海量與高并發(fā)的數(shù)據(jù)環(huán)境中,就顯得先天不足。

memcached

memcached 本身就是為高并發(fā)和快速存取誕生的,并且他還自帶了增量方法。

以下示例開發(fā)語言是 C# 所以采用 EnyimMemcached 作為客戶端,數(shù)據(jù)框架 Entity Framework。

在程序啟動(dòng)時(shí)初始化種子

var date = DateTime.Now;
using (var context = new DbContext())
{
    var seed = context.Order.Where(m => DbFunctions.DiffDays(m.Date, date) == 0).Max(m => (long?)m.Seed) ?? 0;
    new MemcachedClient().Store(StoreMode.Set, "Test_" + date.ToString("yyyyMMdd"), seed.ToString(), TimeSpan.FromHours(25));
}
  1. ASP.NET 可以在 Application_Start 中初始化。
  2. 因?yàn)榘刺爝f增,所以保存過期時(shí)間大于24小時(shí)即可。

插入數(shù)據(jù)的實(shí)體賦值

var date = DateTime.Now;
var seed = new MemcachedClient().Increment("Test_" + date.ToString("yyyyMMdd"), 1, 1, TimeSpan.FromHours(25));
var entity = new Order {
  Code = date.ToString("yyyyMMdd") + seed .ToString().PadLeft(14, '0'),
  Seed = seed,
  Date = date
};
/* 這里將實(shí)體保存到數(shù)據(jù)庫即可 */

文章就寫到這里,這只是 memcached 的一種應(yīng)用,在網(wǎng)站訪問統(tǒng)計(jì)、防刷新機(jī)制等方面你都可以使用它。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 你說你也不知道怎么了,分明是二十幾歲的大好年紀(jì),卻總覺得看淡了一切,不知道該對(duì)什么認(rèn)真。我于是對(duì)你的故事很好奇,做...
    茶木森閱讀 340評(píng)論 0 1
  • 1 乍暖還寒時(shí)候,最難將息。小仙有點(diǎn)發(fā)燒,一個(gè)人靜靜地躲在車子里,淚流了一臉。望著車窗外如豆的燈火,這個(gè)小鎮(zhèn),天剛...
    吾小桐閱讀 479評(píng)論 12 6
  • 最近重溫了步步驚心的小說,不禁感嘆于“第一最好不相見,第二最好不相知”的蕩氣回腸的愛情。很多女生都喜歡看古裝宮廷劇...
    leleqiaokeli閱讀 407評(píng)論 0 4
  • 1,我有一個(gè)很狡猾的主意,找個(gè)自己喜歡的作者,然后從他的書里挖他喜歡提到的人。2,好作者被人民推擁,更好的作者被好...
    我叫13姐閱讀 286評(píng)論 0 0

友情鏈接更多精彩內(nèi)容