首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 實作 Oracle Sequence 功能:高併發安全的身分值產生器

     編輯:關於SqlServer

為什麼需要自訂 Sequence?

  • IDENTITY 只能產生單純遞增數字,無法組合成 YYYYMMDD00001 等業務格式。
  • MAX(id)+1 在高併發下極易產生重複鍵值。
  • 集中式序號表(名稱、起始值、遞增值、目前值)在高併發時鎖定爭用嚴重。

高併發安全方案:利用 IDENTITY + 刪除舊列

-- 為每個業務序號建立專屬表
CREATE TABLE SeqT_0101001 (
    SeqID INT IDENTITY(1,1) PRIMARY KEY,  -- 利用身分欄位保證唯一遞增
    SeqVal VARCHAR(1)                     -- 虛擬欄位,僅佔位
);

-- 取得新序號的預存程序
CREATE PROCEDURE P_GetNewSeqVal_SeqT_0101001
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @NewSeqValue INT;

    -- 插入一列觸發 IDENTITY 產生新值
    INSERT INTO SeqT_0101001 (SeqVal) VALUES ('a');

    -- 取得剛插入的身分值
    SET @NewSeqValue = SCOPE_IDENTITY();

    -- 刪除已用過的列(READPAST 跳過被鎖列,避免阻塞)
    DELETE FROM SeqT_0101001 WITH (READPAST);

    RETURN @NewSeqValue;
END

呼叫方式與格式化

DECLARE @NewSeqVal INT;
EXEC @NewSeqVal = P_GetNewSeqVal_SeqT_0101001;
PRINT @NewSeqVal;

-- 組合成 20080724000056 格式
SELECT CONVERT(CHAR(8), GETDATE(), 112) + RIGHT('00000' + CAST(@NewSeqVal AS VARCHAR(5)), 5) AS mySeq;

核心優勢分析

特性傳統序號表本方案
併發效能單列更新鎖定,嚴重阻塞INSERT + DELETE,鎖定粒度極小,吞吐量達千次/秒
間隙處理無間隙(若交易回滾會留間隙)IDENTITY 本身允許間隙,符合 Sequence 語意
擴充性單表熱點每個序號獨立表,零干擾

限制與替代方案

  • 無法直接在 SELECT 中呼叫(需透過預存程序或函數包裝)。
  • SQL Server 2012+ 內建 CREATE SEQUENCE,支援 NEXT VALUE FOR 直接在查詢中使用,建議優先使用原生功能。
  • 若版本較舊且併發極高,本方案為可行替代;併發中低可考慮 sp_getapplock 序列化傳統寫法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved