Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Utilizzo di una tabella di database come coda

Userei un campo IDENTITY come chiave primaria per fornire l'ID incrementale in modo univoco per ogni elemento in coda e inserire un indice cluster su di esso. Questo rappresenterebbe l'ordine in cui gli articoli sono stati accodati.

Per mantenere gli articoli nella tabella della coda mentre li elabori, avresti bisogno di un campo "stato" per indicare lo stato corrente di un particolare articolo (ad es. 0=in attesa, 1=in elaborazione, 2=elaborato). Ciò è necessario per evitare che un articolo venga elaborato due volte.

Quando si elaborano gli elementi in coda, è necessario trovare l'elemento successivo nella tabella NON attualmente in elaborazione. Ciò dovrebbe avvenire in modo tale da impedire a più processi di prelevare lo stesso articolo da elaborare contemporaneamente, come illustrato di seguito. Nota i suggerimenti per la tabella UPDLOCK e READPAST di cui dovresti essere a conoscenza quando implementi le code.

per esempio. all'interno di uno sproc, qualcosa del genere:

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 l'elaborazione di un elemento non riesce, vuoi riprovare più tardi? In tal caso, dovrai ripristinare lo stato su 0 o qualcosa del genere. Ciò richiederà più riflessione.

In alternativa, non utilizzare una tabella di database come coda, ma qualcosa come MSMQ:ho pensato di metterlo nel mix!