Sql-Server
需要在多執行緒應用程序中以程式方式生成 PK 值
假設我們創建了一個禁用身份的表:
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,等等。