0
當存儲過程鎖我在我的數據庫下表:的SQL Server 2016 - 創造不存在的記錄
------------------------------------------
| EventDefinitions |
------------------------------------------
| EventDefinitionId: uniqueidentifier |
| Code: varchar(63) |
| EventSystem: int |
------------------------------------------
------------------------------------------
| Event |
------------------------------------------
| EventId: uniqueidentifier |
| EventDateTime: datetime2 |
| EventDefinitionId: uniqueidentifier |
------------------------------------------
EventDefinitions(1)< - 事件(N)
EventDefinition具有唯一性約束事件系統和代碼。
我正在創建一個存儲過程,該存儲過程應根據指定的代碼和事件系統創建事件記錄並將其映射到正確的EventDefinition記錄。
如果不存在匹配的EventDefinition,則該過程應創建一個新的EventDefinition。
該過程將由多個應用程序同時執行。
我的目標:
- 的程序必須是並行執行。
儘可能少地鎖定,以便可以同時寫入多個事件記錄。 - 當EventDefinition不存在時,它應該只由一個進程創建。
該過程應該創建某種鎖,以確保只有一次創建帶有指定代碼和事件系統的EventDefinition記錄(否則數據庫將拋出唯一的約束違例異常)。 其他進程應將事件記錄映射到新創建的EventDefinition記錄。
這是我到目前爲止已經試過:
CREATE PROCEDURE dbo.procWriteEvent @eventCode varchar(63), @eventSystem int
AS
DECLARE @eventDefinitionId uniqueidentifier
DECLARE @insertedEventDefinition table(EventDefinitionId uniqueidentifier)
DECLARE @currentLevel varchar(255)
BEGIN TRANSACTION
-- Try read event definition
SET @eventDefinitionId = (SELECT TOP 1 EventDefinitionId FROM EventDefinitions WHERE EventSystem = @eventSystem AND Code = @eventCode)
-- Create event definition if not exists
IF @eventDefinitionId IS NULL
BEGIN
BEGIN TRANSACTION
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
-- Check if event definition was created by an other process
SET @eventDefinitionId = (SELECT TOP 1 EventDefinitionId FROM EventDefinitions WHERE EventSystem = @eventSystem AND Code = @eventCode)
-- Create event definition
IF @eventDefinitionId IS NULL
BEGIN
INSERT INTO EventDefinitions (Code, EventSystem, Severity)
OUTPUT Inserted.EventDefinitionId INTO @insertedEventDefinition
VALUES (@eventCode, @eventSystem, 0)
SET @eventDefinitionId = (SELECT TOP 1 EventDefinitionId FROM @insertedEventDefinition)
END
COMMIT TRANSACTION
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
END
INSERT INTO Events (EventDefinitionId, EventDateTime)
VALUES (@eventDefinitionId, GETDATE())
COMMIT TRANSACTION
的問題,當程序並行執行我當前的SQL代碼產生死鎖。
非常感謝您的幫助。我不是爲什麼我試圖用這種複雜的方式解決這樣一個簡單的問題^^ – musium