[英]Insert new records and update existing recordes in SQL Server Stored procedure
[英]SQL Server 2016 - stored procedure lock when creating not existing records
我的数据库中有以下表格:
------------------------------------------
| EventDefinitions |
------------------------------------------
| EventDefinitionId: uniqueidentifier |
| Code: varchar(63) |
| EventSystem: int |
------------------------------------------
------------------------------------------
| Event |
------------------------------------------
| EventId: uniqueidentifier |
| EventDateTime: datetime2 |
| EventDefinitionId: uniqueidentifier |
------------------------------------------
EventDefinitions(1)<-事件(n)
EventDefinition对EventSystem和Code具有唯一的约束。
我正在研究一个存储过程,该存储过程应基于指定的Code和EventSystem创建一个Event记录并将其映射到正确的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代码在并行执行过程时会产生死锁。
您的代码过于复杂。 SQL Server会执行最多的检查并自行阻止。 只需尝试/捕获插入,如果由于违反UNIQUE约束而失败,请重新读取EventDefinitions。 的种类
CREATE PROCEDURE dbo.procWriteEvent @eventCode varchar(63), @eventSystem int
AS
DECLARE @eventDefinitionId uniqueidentifier
DECLARE @insertedEventDefinition table(EventDefinitionId uniqueidentifier)
DECLARE @currentLevel varchar(255)
-- 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 TRY
INSERT INTO EventDefinitions (Code, EventSystem, Severity)
OUTPUT Inserted.EventDefinitionId INTO @insertedEventDefinition
VALUES (@eventCode, @eventSystem, 0);
SET @eventDefinitionId = (SELECT TOP 1 EventDefinitionId FROM @insertedEventDefinition)
END TRY
BEGIN CATCH
SET @eventDefinitionId = (SELECT TOP 1 EventDefinitionId FROM EventDefinitions WHERE EventSystem = @eventSystem AND Code = @eventCode )
END CATCH
-- proceed with @eventDefinitionId value
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.