Ti consiglio di andare oltre Utilizzo delle tabelle come code. Le code correttamente implementate possono gestire migliaia di utenti e servizi simultanei fino a 1/2 milione di operazioni di accodamento/rimozione dalla coda al minuto. Fino a SQL Server 2005 la soluzione era ingombrante e prevedeva la combinazione di un SELECT
e un UPDATE
in una singola transazione e dare il giusto mix di lock hint, come nell'articolo linkato da GBn. Fortunatamente da SQL Server 2005 con l'avvento della clausola OUTPUT, è disponibile una soluzione molto più elegante e ora MSDN consiglia di utilizzare la clausola OUTPUT:
È possibile utilizzare OUTPUT in applicazioni che utilizzano tabelle come code o per mantenere set di risultati intermedi. Cioè, l'applicazione aggiunge o rimuove costantemente righe dalla tabella
Fondamentalmente ci sono 3 parti del puzzle che devi risolvere affinché funzioni in modo altamente simultaneo:
- Devi togliere automaticamente la coda. Devi trovare la riga, saltare tutte le righe bloccate e contrassegnarla come "rimossa dalla coda" in un'unica operazione atomica, ed è qui che si trova
OUTPUT
entra in gioco la clausola:
with CTE as (
SELECT TOP(1) COMMAND, PROCESSED
FROM TABLE WITH (READPAST)
WHERE PROCESSED = 0)
UPDATE CTE
SET PROCESSED = 1
OUTPUT INSERTED.*;
- Devi devi struttura la tua tabella con la chiave di indice cluster più a sinistra su
PROCESSED
colonna. Se ilID
è stata utilizzata una chiave primaria, quindi spostala come seconda colonna nella chiave cluster. Il dibattito se mantenere una chiave non cluster sull'ID
la colonna è aperta, ma preferisco fortemente non avere eventuali indici secondari non cluster sulle code:
CREATE CLUSTERED INDEX cdxTable on TABLE(PROCESSED, ID);
- Non devi interrogare questa tabella con altri mezzi se non tramite Dequeue. Provare a eseguire operazioni Peek o provare a utilizzare la tabella sia come coda che come un negozio molto probabilmente porterà a deadlock e rallenterà notevolmente il throughput.
La combinazione di rimozione dalla coda atomica, READPAST suggerimento per la ricerca di elementi da rimuovere dalla coda e la chiave più a sinistra dell'indice cluster in base al bit di elaborazione garantisce un throughput molto elevato con un carico altamente simultaneo.