Jako klucza podstawowego użyłbym pola IDENTITY, aby zapewnić niepowtarzalnie zwiększający się identyfikator dla każdego elementu w kolejce i przykleić na nim indeks klastrowany. Reprezentowałoby to kolejność, w jakiej pozycje były umieszczane w kolejce.
Aby utrzymać pozycje w tabeli kolejki podczas ich przetwarzania, potrzebujesz pola „status”, aby wskazać aktualny status danej pozycji (np. 0=oczekuje, 1=przetwarzany, 2=przetwarzany). Jest to konieczne, aby zapobiec dwukrotnemu przetworzeniu elementu.
Przetwarzając elementy w kolejce, musisz znaleźć następny element w tabeli, który NIE jest aktualnie przetwarzany. Musiałoby to odbywać się w taki sposób, aby uniemożliwić wielu procesom pobieranie tego samego elementu do przetworzenia w tym samym czasie, jak pokazano poniżej. Zwróć uwagę na wskazówki dotyczące tabeli UPDLOCK i READPAST, o których należy pamiętać podczas wdrażania kolejek.
np. w sprocie, coś takiego:
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
Jeśli przetwarzanie elementu nie powiedzie się, czy chcesz móc spróbować ponownie później? Jeśli tak, musisz zresetować stan z powrotem do 0 lub coś takiego. To będzie wymagało więcej przemyśleń.
Alternatywnie, nie używaj tabeli bazy danych jako kolejki, ale coś takiego jak MSMQ - po prostu pomyślałem, że dorzucę to do miksu!