sql >> Databasteknik >  >> RDS >> Sqlserver

Använda en databastabell som en kö

Jag skulle använda ett IDENTITET-fält som primärnyckel för att tillhandahålla det unikt ökande ID:t för varje objekt i kö, och klistra ett klustrat index på det. Detta skulle representera den ordning som objekten ställdes i kö.

För att behålla objekten i kötabellen medan du bearbetar dem, skulle du behöva ett "status"-fält för att indikera aktuell status för ett visst objekt (t.ex. 0=väntar, 1=bearbetas, 2=bearbetas). Detta behövs för att förhindra att en vara bearbetas två gånger.

När du bearbetar objekt i kön, måste du hitta nästa objekt i tabellen som INTE bearbetas för närvarande. Detta skulle behöva vara på ett sådant sätt att förhindra att flera processer plockar upp samma artikel för att bearbeta samtidigt som visas nedan. Observera tabelltipsen UPDLOCK och READPAST som du bör vara medveten om när du implementerar köer.

t.ex. inom en sproc, ungefär så här:

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

Om bearbetningen av ett objekt misslyckas, vill du kunna försöka igen senare? Om så är fallet måste du antingen återställa statusen till 0 eller något. Det kommer att kräva mer eftertanke.

Alternativt, använd inte en databastabell som en kö, utan något som MSMQ - tänkte bara lägga det i mixen!



  1. Postgres LEFT JOIN med SUM, saknade poster

  2. Använder bindningsvariabler med dynamisk SELECT INTO-sats i PL/SQL

  3. MySQL:kolumner med låg kardinalitet/selektivitet =hur indexerar man?

  4. Hur får man storleken på ett varchar[n]-fält i en SQL-sats?