Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Usando uma tabela de banco de dados como uma fila


Eu usaria um campo IDENTITY como a chave primária para fornecer o ID de incremento exclusivo para cada item na fila e colocar um índice clusterizado nele. Isso representaria a ordem em que os itens foram enfileirados.

Para manter os itens na tabela de filas enquanto você os processa, você precisa de um campo "status" para indicar o status atual de um determinado item (por exemplo, 0=aguardando, 1=sendo processado, 2=processado). Isso é necessário para evitar que um item seja processado duas vezes.

Ao processar itens na fila, você precisa encontrar o próximo item na tabela que NÃO está sendo processado no momento. Isso precisaria ser de forma a evitar que vários processos pegassem o mesmo item para processar ao mesmo tempo, conforme demonstrado abaixo. Observe as dicas de tabela UPDLOCK e READPAST que você deve estar ciente ao implementar filas.

por exemplo. dentro de um sproc, algo assim:
DECLARE @NextID INTEGER

BEGIN TRANSACTION

-- Find the next queued item that is waiting to be processed
SELECT TOP 1 @NextID = ID
FROM MyQueueTable WITH (UPDLOCK, READPAST)
WHERE StateField = 0
ORDER BY ID ASC

-- if we've found one, mark it as being processed
IF @NextId IS NOT NULL
    UPDATE MyQueueTable SET Status = 1 WHERE ID = @NextId

COMMIT TRANSACTION

-- If we've got an item from the queue, return to whatever is going to process it
IF @NextId IS NOT NULL
    SELECT * FROM MyQueueTable WHERE ID = @NextID

Se o processamento de um item falhar, você deseja tentar novamente mais tarde? Nesse caso, você precisará redefinir o status de volta para 0 ou algo assim. Isso exigirá mais reflexão.

Como alternativa, não use uma tabela de banco de dados como uma fila, mas algo como MSMQ - pensei em colocar isso na mistura!