Есть 3 таблицы. Основная SOME_GROUP и две дочерние, что видно из столбцов GROUP_ID.
У всех трёх таблиц первичный ключ:
CONSTRAINT PK_BLA_BLA PRIMARY KEY CLUSTERED (ID)
Так же у дочерних таблиц есть внешние ключи (GROUP_ID), которые указывают на ID в таблице SOME_GROUP.
Эти строки в запросе приведены для удобства и понимания, что как выполняется.
BEGIN TRANSACTION
SET TRANSACTION ISOLATION LEVEL READ COMMITTED -- REPEATABLE READ
В реальности же из C# кода создаётся транзакция и вызывается получение данных для 3-ёх таблиц. То есть к MSSQL серверу отправляется 3 запроса по очереди в одной транзакции.
Вопрос:
Есть ли вероятность, что на одном из запросов строка...SELECT TOP(@Quantity) ID FROM SOME_GROUP WITH(UPDLOCK) WHERE REPLICATED <> 1
...вернёт другой результат? По идее строки отсортированы по первичному ключу. Если другая транзакция залочит одну из необходимых записей, то мой даже первый запрос будет ждать, пока записи разлочатся, а далее сразу же залочит все записи, которые будут выбраны и в пределах одной транзакции все 3 запроса выполнятся и все 3 раза получение SELECT TOP(@Quantity) вернёт один и тот же результат. Верно?BEGIN TRANSACTION
SET TRANSACTION ISOLATION LEVEL READ COMMITTED -- REPEATABLE READ
SET DEADLOCK_PRIORITY LOW;
DECLARE @Quantity INT = 5;
-- Первый запрос, вызываемый из C# кода в одной транзакции.
-- 1 ------------------------------------------------------------------
UPDATE SOME_GROUP SET REPLICATED = 2
OUTPUT
INSERTED.ID
,INSERTED.NAME
WHERE ID IN(SELECT TOP(@Quantity) ID FROM SOME_GROUP WITH(UPDLOCK) WHERE REPLICATED <> 1)
-- Второй запрос, вызываемый из C# кода в одной транзакции.
-- 2------------------------------------------------------------------
UPDATE SOME_CHILD_ONE SET REPLICATED = 2
OUTPUT
INSERTED.ID
,INSERTED.GROUP_ID
,INSERTED.UPDATED
WHERE GROUP_ID IN(SELECT TOP(@Quantity) ID FROM SOME_GROUP WITH(UPDLOCK) WHERE REPLICATED <> 1) AND REPLICATED <> 1
-- Третий запрос, вызываемый из C# кода в одной транзакции.
-- 3 ------------------------------------------------------------------
UPDATE SOME_CHILD_TWO SET REPLICATED = 2
OUTPUT
INSERTED.ID
,INSERTED.GROUP_ID
,INSERTED.NAME
,INSERTED.CREATED
WHERE GROUP_ID IN(SELECT TOP(@Quantity) ID FROM SOME_GROUP WITH(UPDLOCK) WHERE REPLICATED <> 1) AND REPLICATED <> 1
-- 3 ------------------------------------------------------------------
COMMIT TRANSACTION