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