Ik zou een IDENTITY-veld gebruiken als de primaire sleutel om de uniek oplopende ID voor elk item in de wachtrij te geven, en er een geclusterde index op plakken. Dit zou de volgorde vertegenwoordigen waarin de items in de wachtrij stonden.
Om de items in de wachtrijtabel te houden terwijl u ze verwerkt, hebt u een "status"-veld nodig om de huidige status van een bepaald item aan te geven (bijv. 0=wachten, 1=worden verwerkt, 2=verwerkt). Dit is nodig om te voorkomen dat een artikel twee keer wordt verwerkt.
Wanneer u items in de wachtrij verwerkt, moet u het volgende item in de tabel zoeken dat momenteel NIET wordt verwerkt. Dit zou zo moeten zijn dat wordt voorkomen dat meerdere processen hetzelfde item op hetzelfde moment oppakken om te verwerken, zoals hieronder wordt aangetoond. Let op de tabelhints UPDLOCK en READPAST waar u op moet letten bij het implementeren van wachtrijen.
bijv. binnen een sproc, zoiets als dit:
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
Als het verwerken van een item mislukt, wil je het dan later opnieuw kunnen proberen? Als dit het geval is, moet u de status terugzetten naar 0 of zoiets. Dat vereist meer denkwerk.
U kunt ook geen databasetabel als wachtrij gebruiken, maar iets als MSMQ - ik dacht dat ik dat er even bij kon gooien!