Eu tenho um requisito para criar um procedimento armazenado que emula uma sequência TSQL. Ou seja, sempre fornece um valor inteiro distinto crescente em cada chamada. Além disso, se um número inteiro for passado, ele retornará esse valor se nunca houve um resultado maior ou o próximo número inteiro mais alto disponível. Escusado será dizer que pode haver vários clientes chamando este SP ao mesmo tempo.
Dada uma tabela MetaInfo com as colunas MetaKey varchar (max) e MeatValueLong bigInt. Espera-se que a linha com a MetaKey de 'Internal-ID-Last' contenha o último valor mais alto atribuído. Eu criei o seguinte procedimento armazenado:
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
Minha pergunta é simplesmente: esse procedimento armazenado funciona como esperado (todos os chamadores receberão um resultado exclusivo)?
fonte
Respostas:
Eu já dei uma olhada e o próprio MS oferece uma solução sem bloqueios
http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx
Esta é uma atualização simples, sem dicas de bloqueio, mas eles dizem que ela bloqueia / deadlocks.
Nada muito sobre isso também.
Eu estaria inclinado a adicionar UPDLOCK ao seu ROWLOCK (conforme "tabela como uma fila" (SO), mas sem READPAST). Isso aumentará o isolamento caso um segundo processo comece a ler.
No entanto, o fato de todos os seus processos quererem ler / gravar a mesma linha me faz adivinhar. O READPAST permite simultaneidade segura, mas neste caso é inútil.
Nota: você pode usar a cláusula OUTPUT em vez de uma segunda seleção e não precisará da transação.
HTH ...
fonte
Faltam as seguintes coisas
Sim, deve atender a sua condição. Quando essas situações ocorrem nas transações, ele cria várias instâncias e, posteriormente, todos os chamadores receberão um resultado exclusivo
fonte
Uma solução mais escalável que não requer serialização é a seguinte:
fonte