У меня есть следующие таблицы (сильно упрощенные):
Jobs: JobId, JobState
Data: DataId
JobsData: JobId, DataId
идея JobsData
состоит в том, что любой элемент в Data
может быть связан с одним или несколькими элементами в Jobs
, и каждый элемент в Jobs
может иметь один или несколько элементов из Data
, связанных с ним.
Теперь у меня две транзакции:
-- TRAN1
BEGIN TRAN
INSERT INTO Data VALUES (NewDataId)
INSERT INTO Jobs VALUES (NewJobId, StateInitial)
INSERT INTO JobsData VALUES (NewDataId, NewJobId)
UPDATE Jobs SET JobState=StateReady WHERE JobId=NewJobId
COMMIT TRAN
-- TRAN2
DECLARE @selectedId;
SELECT TOP (1) @selectedId=JobId FROM Jobs WITH (UPDLOCK, READPAST) WHERE JobState=StateReady
IF @selectedId IS NOT NULL
SELECT DataId FROM JobsData WHERE JobId = @selectedId
Код с подсказками по блокировке взят из этого ответа. Его цель состоит в том, чтобы несколько TRAN2
экземпляров работали параллельно и никогда не получали одинаковых JobId
.
Этот код отлично работает с SQL Server (уровень изоляции по умолчанию READ_COMMITTED
), но в SQL Azure TRAN2
иногда работает некорректно - первый SELECT
дает ненулевое значение JobId
, а второй SELECT
дает пустой набор результатов. Я предполагаю, что это связано с тем, что уровень изоляции по умолчанию в SQL Azure равен READ_COMMITTED_SNAPSHOT
.
Я хочу внести минимум изменений, чтобы решить мою проблему - чтобы TRAN2
либо извлекал ноль в первом SELECT
, либо извлекал правильный набор результатов во втором SELECT
.
Какое из совпадений таблицы я могу применить к какому из имеющихся у меня операторов SQL?