Я бы использовал поле IDENTITY в качестве первичного ключа для предоставления уникально увеличивающегося идентификатора для каждого элемента в очереди и прикреплял к нему кластерный индекс. Это будет представлять порядок, в котором элементы были поставлены в очередь.
Чтобы сохранить элементы в таблице очередей во время их обработки, вам потребуется поле «статус», чтобы указать текущее состояние определенного элемента (например, 0 = ожидание, 1 = обрабатывается, 2 = обрабатывается). Это необходимо для предотвращения повторной обработки элемента.
При обработке элементов в очереди вам нужно будет найти следующий элемент в таблице, НЕ обрабатываемой в данный момент. Это должно быть сделано таким образом, чтобы предотвратить одновременное получение несколькими процессами одного и того же элемента для обработки одновременно, как показано ниже. Обратите внимание на табличные подсказки UPDLOCK и READPAST, о которых вы должны знать при реализации очередей.
например. в sproc, что-то вроде этого:
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
Если обработка элемента не удалась, хотите ли вы попробовать его позже? Если это так, вам нужно будет сбросить статус обратно на 0 или что-то еще. Это потребует больше размышлений.
В качестве альтернативы, не используйте таблицу базы данных в качестве очереди, а что-то вроде MSMQ - просто подумал, что я добавлю это в смесь!