를 만들 때 프로 시저 잠금 저장 I했습니다 내 데이터베이스에서 다음과 같은 테이블 :SQL 서버 2016 - 존재하지 않는 기록
------------------------------------------
| EventDefinitions |
------------------------------------------
| EventDefinitionId: uniqueidentifier |
| Code: varchar(63) |
| EventSystem: int |
------------------------------------------
------------------------------------------
| Event |
------------------------------------------
| EventId: uniqueidentifier |
| EventDateTime: datetime2 |
| EventDefinitionId: uniqueidentifier |
------------------------------------------
EventDefinitions (1) < - 이벤트 (n)이
EventDefinition이 고유 제한 조건에있다 EventSystem 및 코드.
나는 이벤트 레코드를 생성하고 지정된 코드 및 EventSystem을 기반으로 정확한 EventDefinition 레코드에 매핑해야하는 저장 프로 시저에 대해 작업하고 있습니다.
일치하는 EventDefinition이 없으면 절차에서 새 EventDefinition을 만들어야합니다.
절차는 여러 응용 프로그램에서 동시에 실행됩니다.
내 목표는 :
- 절차는 병렬로 실행해야합니다.
잠금을 가능한 한 적게 사용하면 여러 이벤트 레코드를 동시에 쓸 수 있습니다. - EventDefinition이없는 경우 하나의 프로세스 만 만들어야합니다.
프로 시저에서는 지정된 Code 및 EventSystem이있는 EventDefinition 레코드가 한 번만 생성되도록 잠금을 설정해야합니다. 그렇지 않으면 DB에서 고유 한 제한 위반 예외가 발생합니다. 다른 프로세스는 이벤트 레코드를 새로 생성 된 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