Sql-Server

需要在多執行緒應用程序中以程式方式生成 PK 值

  • August 15, 2016

假設我們創建了一個禁用身份的表:

CREATE TABLE TestIdentity (
   Id    int NOT NULL,
   abc   varchar(10) NULL,
   CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id)
);

注意:我無權將主鍵設置為啟用身份,因此我必須從應用程序計算下一個 Id 值。

假設從多個連接中插入數據到此表中,Id 欄位值是由 C# 應用程式碼生成的,問題是在多執行緒應用程序中,多個請求可能會生成相同的 id 來插入行。在這種情況下,SQL 伺服器違反了 PK 約束。

減少 PK 約束違規的最佳解決方案是什麼?

您可以嘗試這種技術將單執行緒插入到此表中,但應保證唯一性。您的 C# 程式碼需要在事務中執行以下操作。選擇目前的最大 ID 並保持鎖定,以便其他使用者等待。將 +1 添加到 Id 並插入該行。送出交易

BEGIN TRANSACTION
select @Id = max(Id) from TestIdentity WITH (TABLOCKX,HOLDLOCK)
set @Id += 1
insert into TestIdentity... new row...
COMMIT

確保每個執行緒都有一個從 1 到 N 的唯一標識符 I。以通常的方式生成您的 PK。然後將其乘以 10 並添加 I。這樣,執行緒 #1 生成的密鑰將始終以 1 作為其最後一位。

*這假設總是有 <10 個執行緒,但如果 N > 10 你可以乘以 100,然後加上 I,如果 N > 100 則乘以 1000,等等。

引用自:https://dba.stackexchange.com/questions/146811