У меня есть требование создать хранимую процедуру, которая эмулирует последовательность TSQL. То есть он всегда дает возрастающее целочисленное значение при каждом вызове. Кроме того, если передается целое число, оно должно возвращать это значение, если никогда не было результата, большего или следующего доступного целого числа. Само собой разумеется, что могут быть несколько клиентов, вызывающих этот SP одновременно.
Дана таблица MetaInfo со столбцами MetaKey varchar (max) и MeatValueLong bigInt. Ожидается, что строка с MetaKey 'Internal-ID-Last' будет содержать последнее присвоенное наибольшее значение. Я создал следующую хранимую процедуру:
CREATE PROCEDURE [dbo].[uspGetNextID]
(
@inID bigInt
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
UPDATE MetaInfo WITH (ROWLOCK)
SET MetaValueLong = CASE
WHEN ISNULL(MetaValueLong,0) > @inID THEN MetaValueLong+1
ELSE @inID+1
END
WHERE MetaKey = 'Internal-ID-Last'
SELECT MetaValueLong
FROM MetaInfo
WHERE MetaKey = 'Internal-ID-Last'
COMMIT TRANSACTION
END
У меня простой вопрос, работает ли эта хранимая процедура как ожидалось (всем абонентам будет присвоен уникальный результат)?
источник
Ответы:
Я посмотрел и MS предлагает решение без замков
http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx
Это простое обновление без подсказок о блокировке, но говорят, что оно блокирует / блокирует блокировку.
Ничего особенного в этом тоже нет.
Я был бы склонен добавить UPDLOCK к вашему ROWLOCK (согласно «таблице как очереди» (SO), но без READPAST). Это увеличит изоляцию в случае начала чтения второго процесса.
Однако тот факт, что все ваши процессы хотят читать / записывать одну и ту же строку, заставляет меня задуматься. READPAST позволяет безопасный параллелизм, но в этом случае он бесполезен.
Примечание: вы можете использовать предложение OUTPUT вместо второго выбора, тогда вам не нужна транзакция.
НТН ...
источник
Следующая вещь отсутствует
Да, это должно соответствовать вашему состоянию. Как только такие ситуации возникают в транзакциях, он создает несколько экземпляров, и впоследствии всем вызывающим будет присвоен уникальный результат.
источник
Более масштабируемое решение, которое не требует сериализации, таково:
источник